perm filename PARSER.SAI[OK,TES]2 blob
sn#115798 filedate 1974-08-15 generic text, type T, neo UTF8
00100 ENTRY MANUSCRIPT ;
00200 BEGIN "PARSER"
00300
00400 DEFINE TERNAL = "EXTERNAL" , PRELOAD = "COMMENT" ;
00500 REQUIRE "PUBDFS" SOURCE!FILE ;
00600 REQUIRE "PUBMAI" SOURCE!FILE ;
00700 BEGIN "INNER BLOCK"
00800 REQUIRE "PUBINR" SOURCE!FILE ;
00900 REQUIRE "PUBPRO" SOURCE!FILE ;
01000 EXTERNAL INTEGER PROCEDURE XLENGTH(STRING S);
01100
01200 EXTERNAL RECURSIVE BOOLEAN PROCEDURE TEXTLINE ;
01300
01400 EXTERNAL RECURSIVE PROCEDURE DBREAK ;
01500
01600 EXTERNAL STRING SIMPLE PROCEDURE LABELREF(INTEGER USYMB, LEN) ;
01700
01800 FORWARD INTERNAL RECURSIVE BOOLEAN PROCEDURE CHUNK(BOOLEAN VALID) ;
01900
02000 FORWARD INTERNAL RECURSIVE STRING PROCEDURE E(STRING DEFAULT, STOPWORD) ;
02100
02200 EXTERNAL SIMPLE STRING PROCEDURE PICKFONT(INTEGER F) ;
02300
02400 IFC TENEX THENC
02500 STRING PROCEDURE SCANTO(STRING BRKS; REFERENCE STRING SCANNEE; BOOLEAN INCLUDE) ;
02600 BEGIN
02700 INTEGER DUMMY ;
02800 SETBREAK(LOCAL!TABLE, BRKS, NULL, IF INCLUDE THEN "IA" ELSE "IR") ;
02900 RETURN(SCAN(SCANNEE, LOCAL!TABLE, DUMMY)) ;
03000 END ;
03100
03200 STRING SIMPLE PROCEDURE CVFIL(STRING FILENAME; REFERENCE STRING EXT, PPN) ;
03300 BEGIN
03400 STRING NAME ;
03500 PPN ← IF FILENAME[1 FOR 1] = "<" THEN SCANTO(">", FILENAME, TRUE) ELSE NULL ;
03600 NAME ← SCANTO(".;", FILENAME, FALSE) ;
03700 EXT ← IF FILENAME[1 FOR 1] = "." THEN SCANTO(";", FILENAME, FALSE) ELSE NULL ;
03800 RETURN(NAME) ;
03900 END ;
04000
04100 SIMPLE STRING PROCEDURE INCHWL ;
04200 BEGIN
04300 STRING S ; INTEGER C ;
04400 S ← NULL ;
04500 DO
04600 BEGIN
04700 C ← PBIN ;
04800 IF C = CTLA THEN IF NULSTR(S) THEN ELSE
04900 BEGIN
05000 PBOUT("\") ;
05100 PBOUT(S[∞ FOR 1]) ;
05200 S ← S[1 TO ∞-1] ;
05300 END
05400 ELSE IF C = CTLS THEN OUTSTR(" =" & EOL & "#" & S)
05500 ELSE IF C = EOL OR C = ALTMODE THEN RETURN(S)
05600 ELSE IF C = CTLV THEN S ← S & PBIN
05700 ELSE IF C=RUBOUT THEN
05800 BEGIN
05900 OUTSTR(" XXX" & EOL & "#") ;
06000 S ← NULL ;
06100 END
06200 ELSE S ← S & C ;
06300 END UNTIL FALSE ;
06400 END "INCHWL" ;
06500 ENDC
00100 INTERNAL STRING SIMPLE PROCEDURE RD(INTEGER BRKTBL) ;
00200 BEGIN
00300 COMMENT INPUTSTR = [ [chars] LF line-no TB ]... [chars]
00400 All break tables should break on LF.
00500 RD's value is as if LF line-no TB were null. ;
00600 INTEGER PTR, BYTEWD ; STRING SPTR, RESULT, PART ;
00700 RESULT ← NULL ;
00800 DO BEGIN "PARTIAL"
00900 PART ← SCAN(INPUTSTR, BRKTBL, BRC) ;
01000 IF BRC = LF THEN
01100 BEGIN "MACRO LINE NUMBER"
01200 MACLINE ← SCAN(INPUTSTR, TO!TB!FF!SKIP, DUMMY) ;
01300 IF PART[∞ FOR 1] = LF THEN comment he Appended the break character ;
01400 PART ← IF DEFINING THEN PART & MACLINE & TB ELSE PART[1 TO ∞-1]
01500 ELSE IF DEFINING THEN PART ← PART & LF & MACLINE & TB ;
01600 END "MACRO LINE NUMBER"
01700 ELSE IF BRC = 0 THEN comment, ran out of input ;
01800 IF INPUTCHAN < 0 THEN INPUTSTR ← SWICHBACK comment, done scanning macro body ;
01900 ELSE BEGIN "FROM FILE"
02000 DO BEGIN comment, may be page marks or eof or more lines ;
02100 IF TECOFILE THEN
02200 BEGIN COMMENT CHECK FOR FF AND SUPERFLUOUS LFs ;
02300 SRCLINE ← CVS(CVD(SRCLINE)+1) ;
02400 INPUT(INPUTCHAN, NO!CHARS) ;
02500 WHILE BRC = LF DO
02600 BEGIN
02700 INPUT(INPUTCHAN,ONE!CHAR) ;
02800 INPUT(INPUTCHAN,NO!CHARS) ;
02900 END ;
03000 END
03100 ELSE SRCLINE ← INPUT(INPUTCHAN, TO!TB!FF!SKIP) ;
03200 IF BRC = FF THEN
03300 BEGIN "PGMARK"
03400 PAGEMARKS ← PAGEMARKS + 1 ;
03500 IF TECOFILE THEN
03600 BEGIN
03700 INPUT(INPUTCHAN, ONE!CHAR) ;
03800 SRCLINE ← "0" ;
03900 END ;
04000 WHILE INPGS ∧ LAST=4 ∧ BRC=FF ∧ PAGEMARKS>RH(INPG[INPGX]) DO
04100 IF (INPGX←INPGX+1)>INPGS THEN BEGIN BRC←0 ; EOF←1 END
04200 ELSE IF PAGEMARKS<(K←LH(INPG[INPGX])) THEN
04300 DO BEGIN "SKIP PAGES"
04400 DO INPUT(INPUTCHAN,TO!LF!TB!VT!SKIP)
04500 UNTIL BRC≠TB;
04600 IF BRC = LF THEN
04700 DO BEGIN
04800 SRCLINE←INPUT(INPUTCHAN,TO!TB!FF!SKIP);
04900 IF BRC=FF THEN PAGEMARKS←PAGEMARKS+1 ;
05000 END UNTIL BRC≠FF ;
05100 END "SKIP PAGES"
05200 UNTIL BRC≠TB ∨ PAGEMARKS ≥ K ;
05300 IF ¬EOF THEN
05400 BEGIN COMMENT COMPUTE AND DISPLAY PAGE NUMBER ;
05500 SRCPAGE ← CVS(PAGEMARKS) ;
05600 IF NOT PUBSTD THEN OUTSTR((
05700 IF SWDBACK THEN SPS(LAST-3)
05800 ELSE SP
05900 )&SRCPAGE) ;
06000 SWDBACK ← 0 ;
06100 END ;
06200 END "PGMARK" ;
06300 END
06400 UNTIL BRC ≠ FF ;
06500 MACLINE ← NULL ;
06600 IF FULSTR(LSTOP) ∧ EQU(ERRLINE&"/"&SRCPAGE, LSTOP) THEN
06700 BEGIN
06800 DARN(NULL,VS(THISWD)&VS(THATWD)&VS(INPUTSTR)&CRLF&
06900 VS(OWL[1 TO OAKS])&CRLF&VI(POSN)&VI(BRC)&VI(BRKTBL)) ;
07000 S ← INCHWL ; LSTOP←("0000"&SCAN(S,DIGITA,DUMMY))[∞-4 FOR 5]&S ;
07100 END ;
07200 IF EOF THEN INPUTSTR ← SWICHBACK comment, done scanning a SOURCE!FILE or gen-file;
07300 ELSE BEGIN "FILE LINE"
07400 DO BEGIN "EXPAND TABS"
07500 INPUTSTR ← INPUTSTR & INPUT(INPUTCHAN,TO!LF!TB!VT!SKIP) ;
07600 IF BRC=TB THEN INPUTSTR←INPUTSTR&
07700 (IF PAGESCAN(LAST)≥0 THEN
07800 IF TABTAB=0 THEN
07900 SPS(8-LENGTH(INPUTSTR) MOD 8)
08000 ELSE TABTAB
08100 ELSE TB)
08200 ELSE IF BRC=VT THEN
08300 IF INPUTSTR[∞ FOR 1]=RCBRAK THEN INPUTSTR←INPUTSTR&VT
08400 ELSE
08500 BEGIN "GENVT" COMMENT MAYBE {PAGE!} IN GEN-FILE ;
08600 SPTR ← INPUT(INPUTCHAN, TO!VT!SKIP) ;
08700 IF (PTR ← CVD(SPTR)) ≥ TWO(14)
08800 AND LDB(PLIGHTWD("BYTEWD←ITBL[PTR-TWO(14)]"))=2
08900 THEN
09000 BEGIN
09100 BREAKSET(LOCAL!TABLE,ALTMODE,"IS");
09200 BREAKSET(LOCAL!TABLE,NULL,"O");
09300 S ← STBL[LDB(IXWD(BYTEWD))] ;
09400 INPUTSTR ← INPUTSTR[1 TO ∞-6] &
09500 SCAN(S,LOCAL!TABLE,DUMMY);
09600 END
09700 ELSE INPUTSTR ← INPUTSTR & VT & SPTR & VT ;
09800 END "GENVT"
09900 END "EXPAND TABS"
10000 UNTIL BRC = LF ∨ BRC < 0 ∨ EOF ;
10100 IF BRC≤0 THEN
10200 BEGIN BRC ← LF ;
10300 IF ¬EOF THEN
10400 WARN("=","GARBAGED MANUSCRIPT "&ERRLINE&"/"&SRCPAGE)
10500 END ;
10600 IF DEFINING THEN PART ← PART & LF & SRCLINE & "/" & SRCPAGE & TB ;
10700 END "FILE LINE" ;
10800 END "FROM FILE" ;
10900 IF BRC = LF THEN
11000 IF DEFINING THEN BEGIN BRC←0 ; IF INPUTSTR=COMMAND!CHARACTER THEN
11100 BEGIN PART ← PART & TB ; LOPP(INPUTSTR) ; END END
11200 ELSE IF INPUTSTR = COMMAND!CHARACTER ∨ INPUTSTR = TB THEN
11300 BEGIN
11400 LOPP(INPUTSTR) ;
11500 BRC ← 0 ; comment, keep scanning ;
11600 END
11700 ELSE INPUTSTR ← (BRC ← RCBRAK) & VT & INPUTSTR ;
11800 IF BRC THEN RETURN(IF LENGTH(RESULT)=0 THEN PART
11900 ELSE IF LENGTH(PART)=0 THEN RESULT
12000 ELSE RESULT & PART)
12100 ELSE IF LENGTH(RESULT)=0 THEN RESULT ← PART
12200 ELSE RESULT ← RESULT & PART ;
12300 END "PARTIAL"
12400 UNTIL FALSE ;
12500 END "RD" ;
00100 INTERNAL SIMPLE PROCEDURE RDENTITY ;
00200 BEGIN Comment Sets THATWD, THATTYPE, LIT!ENTITY, LIT!TRAIL ;
00300 STRING SEGMENT, SOURCE ; BOOLEAN DUN, TEXTLN ; INTEGER CC, FAM ; LABEL RETRY ;
00400 TEXTLN ← FALSE ; RETRY: IF CHARTBL[INPUTSTR] LAND TWO(6) THEN RD(TO!VISIBLE) ;
00500 SOURCE ← INPUTSTR ;
00600 FAM ← LDB(FAMILY(SOURCE)) ;
00700 CASE FAM MIN QUOTEQ+1 OF
00800 BEGIN COMMENT BY FAMILY ;
00900 ie 0 ... Letter ;
01000 BEGIN "BUILD ID"
01100 CC ← LENGTH(SEGMENT ← SCAN(SOURCE, ALPHA, BRC)) ;
01200 THATWD ← CAPITALIZE(SEGMENT);
01300 THATTYPE ← 0 ;
01400 END "BUILD ID" ;
01500 ie 1 ... Digit ;
01600 BEGIN "BUILD INTEGER"
01700 CC ← LENGTH(THATWD ← "0" & SCAN(SOURCE, DIGITA, BRC)) - 1 ;
01800 THATTYPE ← -1 ;
01900 END "BUILD INTEGER" ;
02000 ie 2 ... EMPTYQ ; IMPOSSIBLE("RDENTITY") ;
02100 ie 3 ... Terminal ;
02200 BEGIN "MAYBE TEXT"
02300 IF LDB(SPECIES("THATWD ← LOP(SOURCE)")) = 0 THEN TEXTLN ← TRUE ;
02400 CC ← 1 ; THATTYPE ← -TERQ ;
02500 END "MAYBE TEXT" ;
02600 ie 4 ... Quote ;
02700 IF SOURCE = """" THEN
02800 BEGIN "STRING CONSTANT"
02900 DUN ← FALSE ; THATWD ← "7" ; LOPP(SOURCE) ; CC ← 1 ; ie skip " ;
03000 DO BEGIN "TO NEXT QUOTE"
03100 SEGMENT ← SCAN(SOURCE, TO!QUOTE!APPD, BRC) ;
03200 CC ← CC + LENGTH(SEGMENT) ;
03300 IF BRC ≠ """" THEN
03400 BEGIN "ERROR"
03500 THATWD ← THATWD & SEGMENT[1 TO ∞-1] ; DUN ← TRUE ;
03600 WARN("=","Omitted Right Quote From: "&THATWD) ;
03700 END "ERROR"
03800 ELSE IF SOURCE = """" THEN
03900 BEGIN "INTERNAL QUOTE"
04000 THATWD ← THATWD & SEGMENT ;
04100 LOPP(SOURCE) ; CC ← CC + 1 ; ie skip second " ;
04200 END "INTERNAL QUOTE"
04300 ELSE
04400 BEGIN "END STRING"
04500 THATWD ← THATWD & SEGMENT[1 TO ∞-1] ;
04600 DUN ← TRUE ;
04700 END "END STRING"
04800 END "TO NEXT QUOTE"
04900 UNTIL DUN ;
05000 THATTYPE ← -1 ;
05100 END "STRING CONSTANT"
00100 ELSE
00200 BEGIN "OCTAL CONSTANT"
00300 LOPP(SOURCE) ; THATTYPE ← -1 ;
00400 CC ← LENGTH(SEGMENT ← SCAN(SOURCE, DIGITA, BRC)) + 1 ;
00500 THATWD ← "8" & (DUMMY←CVO(SEGMENT)) ; COMMENT a one-character string ;
00600 IF NOT INPICHAR THEN TES 12/6/73 ;
00700 IF DUMMY='0 ∨ '11≤DUMMY≤'15 ∨ DUMMY=ALTMODE ∨ DUMMY=RUBOUT THEN
00800 BEGIN
00900 WARN("ILL OCTAL",
01000 "Illegal octal constant (represents illegal character) "&CVOS(DUMMY)) ;
01100 THATWD ← "7" ;
01200 END ;
01300 END "OCTAL CONSTANT" ;
01400 ie 5 ... Other ;
01500 BEGIN "SINGLE CHARACTER"
01600 THATTYPE ← -FAM ; CC ← 1 ; THATWD ← LOP(SOURCE) ;
01700 IF FAM = MISCQ THEN CASE LDB(SPECIES(THATWD)) OF
01800 BEGIN
01900 [4] ie ∞ ; BEGIN THATTYPE ← 0 ; THATWD ← "!INF" END ;
02000 [0] BEGIN "ILL CHAR"
02100 WARN("=","EXTRANEOUS '" & CVOS(THATWD) & " in command line") ;
02200 LOPP(INPUTSTR) ; GO TO RETRY ;
02300 END "ILL CHAR" ;
02400 [MISCMAX]
02500 END ;
02600 END "SINGLE CHARACTER" ;
02700 END ; COMMENT BY FAMILY ;
02800 LIT!ENTITY ← INPUTSTR[1 TO CC] ;
02900 INPUTSTR ← SOURCE ;
03000 LIT!TRAIL ← IF TEXTLN THEN NULL ELSE IF CHARTBL[INPUTSTR] LAND TWO(6) THEN RD(TO!VISIBLE) ELSE NULL ;
03100 END "RDENTITY" ;
00100 INTEGER SIMPLE PROCEDURE ESTIMATE ;
00200 BEGIN
00300 INTEGER TOT, LEFT ;
00400 TOT ← LEFT ← IF AREAIXM ∧ 0≤STATUS≤2 THEN LINES ELSE LINECT(IXTEXT) ;
00500 LEFT ← LEFT + XGENLINES; RKJ;
00600 IF STATUS=1 THEN LEFT ← LEFT - (LINE + COVERED + PINE) ;
00700 IF NOT NOPGPH THEN LEFT ← LEFT - ( 1+(ABOVEX MAX BRKABX)-(BELOWX MIN BRKBLX)+
00800 (IF NOFILL THEN LEADNM ELSE IF FIRST THEN LEADFM ELSE SPREADM-1) ) ;
00900 RETURN(IF LEFT<0 THEN -(LEFT+TOT) ELSE LEFT) ;
01000 END "ESTIMATE" ;
01100
01200 INTEGER SIMPLE PROCEDURE EMPTYCOLS ;
01300 IF COL = 0 THEN RETURN(COLS)
01400 ELSE BEGIN
01500 INTEGER COUNT, COLUMN ; COUNT ← 0 ;
01600 FOR COLUMN ← (COL - 1) MOD COLS + 1 THRU COLS DO
01700 IF AA[COLUMN, 0] = 0 ∧ AA[COLUMN+COLS,0] = 0 THEN COUNT ← COUNT + 1 ;
01800 RETURN(COUNT-(IF ESTIMATE<0 THEN 1 ELSE 0)) ;
01900 END "EMPTYCOLS" ;
02000
02100 STRING PROCEDURE TYPEIN ;
02200 BEGIN
02300 IF NOT ON THEN RETURN (NULL); RKJ: 5-10-74 ;
02400 IF NOT SWDBACK THEN OUTSTR(CRLF) ;
02500 OUTSTR("#") ; SWDBACK ← TRUE ;
02600 RETURN(INCHWL) ;
02700 END "TYPEIN" ;
02800
02900 INTERNAL STRING SIMPLE PROCEDURE EVALV(STRING THISWD ; INTEGER IX, TYP) ;
03000 BEGIN comment, evaluates the "variable" in THISWD ;
03100 CASE TYP OF
03200 BEGIN COMMENT BY TYPE ;
03300 [0] BEGIN IF ON THEN WARN("=","Undefined Identifier " & THISWD) ; RETURN(VIRGIN) END ;
03400 [GLOBALTYPE] RETURN(STBL[IX]) ;
03500 [LOCALTYPE] RETURN(SSTK[IX]) ;
03600 [INTERNTYPE]
03700 BEGIN "INTERNAL"
03800 RETURN(CASE IX OF (
03900 ie 0 ... LINES ; CVS(ABS(ESTIMATE)),
04000 ie 1 ... COLUMNS; CVS(CASE STATUS+1 OF (
04100 ie -1 ... no place area ; 0,
04200 ie 0 ... unopened area ; COLS-(IF ESTIMATE<0 THEN 1 ELSE 0),
04300 ie 1 ... open area ; EMPTYCOLS,
04400 ie 2 ... closed area ; 0,
04500 ie 3 ... dis-declared ; 0) ),
04600 ie 2 ... ! ; !,
04700 ie 3 ... SPREAD ; CVS(SPREADM),
04800 ie 4 ... FILLING; IF ¬FILL THEN "0" ELSE IF ADJUST THEN "1" ELSE "-1",
04900 ie 5 ... !SKIP! ; CVS(MANUS!SKIP!),
05000 ie 6 ... !SKIPL!; CVS(LH(MANUS!SKIP!)),
05100 ie 7 ... !SKIPR!; CVS(RH(MANUS!SKIP!)),
05200 ie 8 ... NULL ; NULL,
05300 ie 9 ... ∞ ; CVS(INF),
05400 ie 10... FOOTSEP; FOOTSEP,
05500 ie 11... TRUE ; "-1",
05600 ie 12... FALSE ; "0",
05700 ie 13... INDENT1; CVS(FIRSTIM),
05800 ie 14... INDENT2; CVS(RESTIM),
05900 ie 15... INDENT3; CVS(RIGHTIM),
06000 ie 16... LMARG ; CVS(LMARG),
06100 ie 17... RMARG ; CVS(RMARG),
06200 ie 18... CHAR ; IF NOPGPH THEN "0" ELSE CVS(POSN), TES 0->"0" 5/26/74;
06300 ie 19... CHARS ; CVS(IF NOPGPH THEN RMARG-LMARG ELSE MAXIM-POSN),
06400 ie 20... LINE ; CVS(IF STATUS=1 THEN LINE ELSE 0),
06500 ie 21... COLUMN ; CVS(IF STATUS=1 THEN COL ELSE 0),
06600 ie 22... TOPLINE; CVS(LINE1(IF AREAIXM THEN AREAIXM ELSE IXTEXT)),
06700 ie 23... XCRIBL; CVS(XCRIBL),
06800 ie 24... CHARW ; CVS(CHARW),
06900 ie 25... XGENLINES; CVS(XGENLINES),
07000 ie 26... UNDERLINE ; VUNDERLINE, TES 10/22/73 ;
07100 ie 27... THISDEVICE ; TES 11/15/73 ;
07200 CASE ABS(DEVICE)-1 OF ("LPT","TTY","MIC","XGP"),
07300 ie 28... THISFONT ; IF THISFONT < 10 THEN
07400 THISFONT+"0" ELSE THISFONT+("A"-10),
07500 ie 29... FOOTGAP ; CVS(FOOTGAP), TES 11/27/73 ;
07600 ie 30... FOOTSEPFONT ; PICKFONT(FSFONT)[3 FOR 1], TES 11/29/73 ;
07700 ie 31... TTY ; TYPEIN, TES 11/29/73 ;
07800 ie 32... ODDLEFTBORDER ; CVS(ODDLEFTBORDER), TES 6/11/74 ;
07900 ie 33... EVENLEFTBORDER ; CVS(EVENLEFTBORDER), TES 6/11/74 ;
08000 ie 34... FULLFILE ; INFILE, TES 6/13/74 ;
08100 WARN(NULL,"PUB BUG: EVALV CASE IX")
08200 ) ) ;
08300 END "INTERNAL" ;
08400 [MANTYPE] WARN("=",THISWD&" in an expression") ;
08500 [PORTYPE] RETURN(THISWD) ;
08600 [PUNITTYPE] RETURN(PATT!VAL("PATT!STRS(IX)")) ;
08700 [AREATYPE] RETURN(THISWD) ;
08800 [UNITTYPE] RETURN(CTR!VAL("PATT!STRS(IX)"))
08900 END COMMENT BY TYPE ; ;
09000 RETURN(NULL) ;
09100 END "EVALV" ;
09200
09300 INTERNAL STRING SIMPLE PROCEDURE VEVAL ; RETURN(EVALV(THISWD, IX, THISTYPE)) ;
00100 INTERNAL RECURSIVE STRING PROCEDURE PASS ; comment Value is always NULL ;
00200 BEGIN comment, Load up WD[0:1], TYPE[0:1], SYMB, and IX for the parser.
00300 Calls CHUNK recursively! PASS will expand macro calls,
00400 replace macro/response arguments with their actual values,
00500 skip over comments, and execute asides.;
00600 PRELOAD!WITH 0, [3]3, 2, [4]3, 0, 1, 0, 4, [5]0, 5, 0, 0, 6, [7]0, 7, 0 ;
00700 OWN INTEGER ARRAY SCANTYPE[-15:15] ; comment, computes small case index ;
00800 BOOLEAN FINAL ;
00900 DO BEGIN "LOAD WD 0"
01000 IF ¬THATISFULL THEN RDENTITY ;
01100 THISWD ← THATWD ;
01200 THISTYPE ← IF THATTYPE THEN THATTYPE comment, non-identifier ;
01300 ELSE IF SYMLOOK(THATWD) THEN LDB(TYPEN(SYMBOL))
01400 ELSE 0 ; comment, undeclared identifier ;
01500 IF THISTYPE ≠ -TERQ THEN RDENTITY ;
01600 IF THISISID THEN
01700 BEGIN "IDENTIFIER"
01800 SYMB ← SYMBOL ;
01900 IF ¬DCLR!ID ∧ THATISID ∧ SYMLOOK(THISWD & SP & THATWD) THEN
02000 BEGIN comment, two-word macro name ;
02100 THISWD ← SYM[SYMB←SYMBOL] ; THISTYPE ← MACROTYPE ;
02200 IX ← LDB(IXN(SYMBOL)) ; RDENTITY ;
02300 END
02400 ELSE BEGIN SYMBOL←SYMB ; IF NULSTR(SYM[SYMB]) THEN ENTERSYM(THISWD,0) ; IX←LDB(IXN(SYMB)) ;END ;
02500 END "IDENTIFIER" ;
02600 FINAL ← FALSE ;
02700 DO CASE SCANTYPE[THISTYPE] OF
02800 BEGIN COMMENT DETECT ;
02900 ie 0 ... Nothing to do ; BEGIN END ;
03000 ie 1 ... $ ; IF NEXTSCH("(") THEN
03100 BEGIN EMPTYTHAT ; THISWD←"⊂" ;
03200 IX ← LDB(SPECIES(THISWD)) ; THISTYPE ← -TERQ ;
03300 END
03400 ELSE IX←LDB(SPECIES(THISWD)) ; COMMENT REPLACED OLD "ASIDE" (UNPUBL. FEATURE) 2/20/73 ;
03500 ie 2 ... < Family ; IF ITSCH(<) AND NEXTSCH(<) THEN
03600 BEGIN "<<COMMENT>>" SETBREAK(LOCAL!TABLE, ">"&RCBRAK&LF, NULL, "IS") ;
03700 DO RD(LOCAL!TABLE) UNTIL BRC=">" ∧ INPUTSTR=">" ∨ BRC=RCBRAK ∧ INPUTSTR=VT ;
03800 IF BRC=">" THEN RD(ONE!CHAR)
03900 ELSE BEGIN WARN("=","Unterminated <<comment>>") ; INPUTSTR←BRC&INPUTSTR END ;
04000 EMPTYTHIS ; EMPTYTHAT ;
04100 END "<<COMMENT>>"
04200 ELSE IX ← LDB(SPECIES(THISWD)) ; ie relational operator ;
04300 ie 3 ... Expression Operators ; IX ← LDB(SPECIES(THISWD)) ;
04400 ie 4 ... Terminal ;
04500 BEGIN
04600 IF ITSCH("]") ∧ INPUTSTR="$" THEN
04700 BEGIN LOPP(INPUTSTR) ; THISWD ← RCBRAK END ;
04800 EMPTYTHAT ; IX ← LDB(SPECIES(THISWD)) ;
04900 END ; Comment NOTE!! }),]⊂;
05000 ie 5 ... internal variable ; IF ¬DCLR!ID ∧ IX ≥ 200 THEN
05100 BEGIN "OPERATOR"
05200 IX ← IX-200 ; comment e.g., NOT → ¬ ;
05300 THISTYPE ← -LDB(FAMILY(IX)) ;
05400 IX ← LDB(SPECIES(IX)) ;
05500 END "OPERATOR" ;
00100 ie 6 ... reserved word ; IF IX=IXCOMMENT∧ ¬DCLR!ID THEN
00200 BEGIN "COMMENT"
00300 INPUTSTR ← LIT!ENTITY & INPUTSTR ;
00400 DO RD(TO!SEMI!SKIP) UNTIL BRC=";" ∨ INPUTSTR=VT ;
00500 IF BRC ≠ ";" THEN BEGIN WARN("=","Unterminated COMMENT;") ; INPUTSTR←BRC&INPUTSTR END ;
00600 EMPTYTHIS ; EMPTYTHAT ; ;
00700 END "COMMENT" ;
00800 ie 7 ... macro name ; IF ¬DCLR!ID THEN
00900 BEGIN "EXPAND MACRO"
01000 INTEGER MACIX, MACSYM, ARGS, ARG, ARGSYM, NAMES, K ; BOOLEAN WASLPAR, DO!IT, DUMSEMI ;
01100 DO!IT ← ON OR ODDMAC(IX) ; comment Whether to actually expand it, or make it NULL;
01200 MACIX ← IX ; MACSYM ← SYMB ; ARGS ← NUMARGS(MACIX) ; DUMSEMI ← FALSE ;
01300 IF ARGS THEN
01400 BEGIN "SCAN ARGS"
01500 STRING ARRAY ACTUAL[1:ARGS] ;
01600 IF ¬(WASLPAR ← NEXTSCH("(")) THEN INPUTSTR ← LIT!ENTITY&LIT!TRAIL&INPUTSTR ;
01700 comment , Back up. Pretend just passed comma. ; THISWD ← "," ; EMPTYTHAT ;
01800 NAMES ← NAMEPAR(MACIX) ; comment bit table for name parameters ;
01900 FOR ARG ← 1 THRU ARGS DO
02000 BEGIN "EACH ACTUAL"
02100 IF ¬ITSCH(",") THEN ACTUAL[ARG] ← NULL comment , omitted argument;
02200 ELSE BEGIN RD(TO!VISIBLE) ;
02300 IF NAMES LAND TWO(ARGS-ARG) = 0 THEN
02400 BEGIN PASS ; ACTUAL[ARG] ← E(NULL, NULL&'0) ; END
02500 ELSE BEGIN "CALL BY NAME"
02600 IF BRC ≠ """" THEN
02700 BEGIN comment , Unquoted Call-By-Name ;
02800 IF (K←BRC)="|" THEN RD(ONE!CHAR) ;
02900 ACTUAL[ARG]←RD(IF K="|" THEN TO!VBAR!SKIP
03000 ELSE IF WASLPAR THEN TO!COMMA!RPAR ELSE TO!TERQ!CR) ;
03100 IF BRC=CR ∧ ¬WASLPAR THEN
03200 BEGIN comment force a semicolon ;
03300 INPUTSTR ← ";" & INPUTSTR ;
03400 DUMSEMI ← TRUE ;
03500 END ;
03600 PASS ;
03700 END
03800 ELSE BEGIN PASS ; ACTUAL[ARG]←E(NULL,0) END ;
03900 END "CALL BY NAME"
04000 END
04100 END "EACH ACTUAL" ;
00100 WHILE ITSCH(",") DO
00200 BEGIN
00300 WARN("=","Too Many Arguments to "&SYM[MACSYM]) ;
00400 PASS ; E(NULL, 0) ;
00500 END ;
00600 IF ITSCH(")") ∧ WASLPAR THEN BEGIN comment Easy case; END
00700 ELSE BEGIN
00800 IF WASLPAR THEN WARN("=","Missed ) After Macro Call") ;
00900 comment Back Up -- SWICH only saves THATWD ;
01000 IF THATISFULL THEN comment Unlikely; INPUTSTR ← LIT!ENTITY&LIT!TRAIL&INPUTSTR ;
01100 IF THISISFULL ∧ ¬DUMSEMI THEN BEGIN THATWD ← LIT!ENTITY ← THISWD ;
01200 LIT!TRAIL ← IF THISTYPE<-1 THEN NULL ELSE SP ;
01300 THATTYPE ← THISTYPE MIN 0 END ELSE EMPTYTHAT ;
01400 END ;
01500 IF DO!IT THEN
01600 BEGIN "STACK ARGUMENTS"
01700 IF LAST + ARGS > SIZE THEN GROWNESTS ;
01800 FOR ARG ← 1 THRU ARGS DO
01900 SNEST[LAST + ARG] ← ACTUAL[ARG] ;
02000 LAST ← LAST + ARGS ;
02100 END "STACK ARGUMENTS" ;
02200 END "SCAN ARGS" ;
02300 IF DO!IT THEN SWICH(SSTK[BODY(MACIX)], -1, ARGS)
02400 ELSE BEGIN THISWD ← "7" ; THISTYPE ← -1 END ; ie, Replace by NULL ("") ;
02500 END "EXPAND MACRO" ;
02600 END COMMENT DETECT ; UNTIL (FINAL ← ¬FINAL) ;
02700 END "LOAD WD 0" UNTIL THISISFULL ;
02800 RETURN(NULL) ;
02900 END "PASS" ;
00100 INTERNAL RECURSIVE STRING PROCEDURE E(STRING DEFAULT, STOPWORD) ;
00200 COMMENT Scan a SAIL-Like <Expression>. First check trivial case. ;
00300 IF ITS(IF) THEN
00400 BEGIN "CONDITIONAL EXPRESSION"
00500 STRING BOOLX, THENX, ELSEX ; BOOLEAN WASON ;
00600 WASON ← ON ; PASS ;
00700 BOOLX ← E(NULL, "THEN") ; ON ← WASON ∧ TRUESTR(BOOLX) ;
00800 IF ITS(THEN) THEN PASS ELSE WARN("=","Missed THEN in conditional expression "&THISWD) ;
00900 THENX ← E(NULL, "ELSE") ;
01000 IF ITS(ELSE) THEN
01100 BEGIN
01200 ON ← WASON ∧ FALSTR(BOOLX) ; PASS ;
01300 ELSEX ← E(NULL, STOPWORD) ;
01400 END
01500 ELSE ELSEX ← NULL ;
01600 ON ← WASON ;
01700 RETURN(IF TRUESTR(BOOLX) THEN THENX ELSE ELSEX) ;
01800 END "CONDITIONAL EXPRESSION"
01900 ELSE IF THISTYPE = -TERQ ∨ THISTYPE = MANTYPE ∨ ITSV(STOPWORD) THEN
02000 RETURN(DEFAULT) comment omitted expression ;
02100 ELSE IF THISTYPE ≥ -1 ∧ (THATTYPE = -TERQ ∨ THATTYPE=MANTYPE ∨ NEXTSV(STOPWORD)) THEN
02200 RETURN(SPASS("IF THISISCON THEN THISWD[2 TO ∞] ELSE VEVAL"))
02300 ELSE IF THISISID ∧ NEXTSCH(←) THEN comment, Assignment Expression ;
02400 RETURN(VASSIGN(SYMB, THISTYPE, IX, E(IPASS(PASS), STOPWORD)))
02500 ELSE
02600 BEGIN "SIMPLE EXPRESSION"
02700 STRING ANY, comment, result of A∨B∨...: has value of first TRUE operand;
02800 ALL, comment, result of A∧B∧...: has value of first FALSE operand;
02900 COMPARE, comment, result of A<B≤...: TRUE if all relations are TRUE;
03000 LEFT, comment, preceding right comparator, saved for another comparison;
03100 BOUNDARY, comment, result of A MAX B MIN... ;
03200 PRODUCT, comment, result of * / MOD & ;
03300 PRIMARY ; comment, <const>|<var>|( <expr> )|<unary><primary>|<primary><substr spec> ;
03400 INTEGER OROP, comment, =0 signals ∨ waiting for right operand ;
03500 ANDOP, NOTOP, comment, =0 signals ∧ or ¬ operator waiting ;
03600 RELOP, ODDOP, BOUNDOP, ADDOP, MULOP, comment, ≥0 signals operator waiting ;
03700 UNARYOP, comment, ≥0 signals unary operators waiting ;
03800 U, comment, last of a series of unary operators ;
03900 SS1, comment, starting byte number in substring spec ;
04000 SAVEINF, comment, saved outside value of ∞ ;
04100 SYMPTR, comment, symbol table number of identifier ;
04200 IDTYPE, comment, type field in its NUMBER entry ;
04300 ICOMPARE, ILEFT, IBOUNDARY, ISUM, IPRODUCT, IPRIMARY ; comment, CVD(corresponding string);
04400 BOOLEAN WASONA, WASONO ; comment value of ON before a series of conjuncts or disjuncts ;
04500 DEFINE TRYFAMILY(FAM) = "IF THISTYPE=-FAM THEN IPASS(IX)";
00100 COMMENT Multiple Unary operators ( + , - , ABS , LENGTH , XLENGTH , and ↑ ) are combined
00200 into a single operator by inventing new operators such as
00300 "-ABS" and "ABS LENGTH" ;
00400 DEFINE P = "0", comment, +X ; M = "1", comment, -X ; A = "2", comment, ABS X ;
00500 MA = "3", comment, -ABS X ; C = "4", comment, ↑X ;
00600 L = "5", comment, LENGTH(X) ; ML = "6", comment -LENGTH(X) ;
00700 AL = "7", comment, ABS LENGTH(X) ; MAL = "8", comment, -ABS LENGTH(X) ;
00740 Z = "9", comment, XLENGTH(X) ; MZ = "10", comment -XLENGTH(X) ;
00770 AZ = "11", comment, ABS XLENGTH(X) ; MAZ = "12"; comment, -ABS XLENGTH(X) ; TES 8/14/74 ;
00800 PRELOAD!WITH comment RIGHT OPERATOR
00900 ---------------------------------
01000 LEFT OPERATOR + - ABS ↑ LENGTH XLENGTH
01100 ------------- --- --- --- --- -------- ---------
01200 none; P, M, A, C, L, Z,
01300 comment P ; P, M, A, P, L, Z,
01400 comment M ; M, P, MA, M, ML, MZ,
01500 comment A ; A, A, A, A, AL, AZ,
01600 comment MA ; MA, MA, MA, MA, MAL, MAZ,
01700 comment C ; P, M, A, C, L, Z ;
01800 OWN INTEGER ARRAY COMBINE[-1:4,0:5] ;
01900 COMMENT This is a top-down expression parser, but iteration is used
02000 instead of recursion for rapidity ;
02100
02200 OROP ← ANDOP ← NOTOP ← RELOP ← BOUNDOP ← ADDOP ← MULOP ← -1 ;
02300 WASONO ← ON ;
02400 DO BEGIN "DISJUNCTS" ie Operands of ∨ ;
02500 WASONA ← ON ;
02600 DO BEGIN "CONJUNCTS" ie Operands of ∧ ;
02700 WHILE THISTYPE = -NOTQ DO BEGIN NOTOP ← -1 - NOTOP ; PASS END ;
02800 ICOMPARE ← TRUE ;
02900 DO BEGIN "COMPARATORS" ie Operands of < = etc. ;
03000 ODDOP ← TRYFAMILY(ODDQ) ELSE -1 ;
03100 DO BEGIN "BOUNDS" ie Operands of MAX and MIN ;
03200 DO BEGIN "TERMS" ie Operands of + - ≡ ⊗ ;
03300 DO BEGIN "FACTORS" ie Operands of * / MOD & ;
03400 UNARYOP ← -1 ; ie check for Unary Operators ;
03500 WHILE UNARYOP≤3 ie no, P, M, A, or MA left operator ;
03600 AND 0 ≤ (U ← TRYFAMILY(ADDQ) ELSE -1) ie some right operator ;
03700 DO UNARYOP ← COMBINE[UNARYOP, U] ;
03800 comment PRIMARY ;
03900 IF THISISCON THEN BEGIN PRIMARY ← THISWD[2 TO ∞] ; PASS END
04000 ELSE IF THISISID THEN
04100 IF ITSV(STOPWORD) THEN
04200 BEGIN
04300 PRIMARY ← DEFAULT ;
04400 WARN("=","Ill-Formed Expression" & THISWD) ;
04500 END
04600 ELSE BEGIN PRIMARY ← VEVAL ; PASS END
04700 ELSE IF ITSCH("(") THEN
04800 BEGIN "( <EXPR> )"
04900 PASS ; PRIMARY ← E(DEFAULT, 0) ;
05000 IF ITSCH(")") THEN PASS ELSE WARN("=","Missed )") ;
05100 END "( <EXPR> )"
05200 ELSE BEGIN WARN("=","Ill-Formed expression" & THISWD) ; PRIMARY ← DEFAULT END ;
00100 WHILE THISTYPE=-BROKQ DO ie Substring Specifications ;
00200 BEGIN "SUBSPEC"
00300 PASS ; SAVEINF ← INF ; INF ← LENGTH(PRIMARY) ;
00400 SS1 ← CVD(E("1", IF NEXTS(TO) THEN "TO" ELSE "FOR")) ;
00500 IF ITS(TO) THEN BEGIN PASS ; PRIMARY←PRIMARY[SS1 TO CVD(E("0",0))] END
00600 ELSE IF ITS(FOR) THEN BEGIN PASS ; PRIMARY←PRIMARY[SS1 FOR CVD(E("1",0))] END
00700 ELSE PRIMARY ← PRIMARY[SS1 FOR 1] ;
00800 MANUS!SKIP! ← !SKIP! ;
00900 IF ITSCH(]) THEN PASS ELSE WARN("=","Missed ] in substring spec " & THISWD) ;
01000 INF ← SAVEINF ;
01100 END "SUBSPEC" ;
01200 IF UNARYOP≤3 THEN IPRIMARY ← CVD(PRIMARY) ; ie both int & str versions maintained when needed ;
01300 IF UNARYOP ≥ 0 THEN IF UNARYOP=C THEN IPRIMARY←CVD(PRIMARY←CAPITALIZE(PRIMARY))
01400 ELSE PRIMARY ← CVS(IPRIMARY ← CASE UNARYOP OF (IPRIMARY, -IPRIMARY,
01500 ABS IPRIMARY, -ABS IPRIMARY, 0, LENGTH(PRIMARY), -LENGTH(PRIMARY),
01600 ABS LENGTH(PRIMARY), -ABS LENGTH(PRIMARY),
01650 XLENGTH(PRIMARY), -XLENGTH(PRIMARY),
01675 ABS XLENGTH(PRIMARY), -ABS XLENGTH(PRIMARY) ) ) ; TES 8/14/74;
01700 IF MULOP<0 THEN BEGIN PRODUCT ← PRIMARY ; IPRODUCT ← IPRIMARY END
01800 ELSE IF MULOP = 3 THEN IPRODUCT ← CVD(PRODUCT ← PRODUCT & PRIMARY)
01900 ELSE PRODUCT ← CVS(IPRODUCT ← IF IPRIMARY=0 ∨ ¬ON THEN 0 ELSE CASE MULOP OF
02000 (IPRODUCT*IPRIMARY, IPRODUCT DIV IPRIMARY, IPRODUCT MOD IPRIMARY) ) ;
02100 MULOP ← TRYFAMILY(MULQ) ELSE -1 ;
02200 END "FACTORS" UNTIL MULOP < 0 ;
02300
02400 ISUM ← CASE ADDOP+2 OF (IPRODUCT, IPRODUCT, ISUM + IPRODUCT,
02500 ISUM - IPRODUCT, ISUM ≡ IPRODUCT, ISUM ⊗ IPRODUCT) ;
02600 ADDOP ← TRYFAMILY(ADDQ) ELSE IF ADDOP<0 THEN -1 ELSE -2 ;
02700 END "TERMS" UNTIL ADDOP < 0 ;
02800
02900 IBOUNDARY ← CASE BOUNDOP+2 OF (ISUM, ISUM, IBOUNDARY MAX ISUM, IBOUNDARY MIN ISUM) ;
03000 BOUNDOP ← TRYFAMILY(BOUNDQ) ELSE IF ADDOP=-1 ∧ BOUNDOP<0 THEN -1 ELSE -2 ;
03100 END "BOUNDS" UNTIL BOUNDOP < 0 ;
03200 BOUNDARY ← IF BOUNDOP = -1 THEN PRODUCT ie, hasn't changed since then; ELSE CVS(IBOUNDARY) ;
03300 IF ODDOP≥0 THEN BOUNDARY←CVS(IBOUNDARY←(IBOUNDARY MOD 2)=ODDOP);
03400 IF ICOMPARE THEN CASE RELOP+2 OF BEGIN comment SAIL Bug precludes case expression with relationals;
03500 BEGIN END ; BEGIN END ; ICOMPARE←ILEFT<IBOUNDARY; ICOMPARE←ILEFT>IBOUNDARY; ICOMPARE ←
03600 EQU(LEFT,BOUNDARY); ICOMPARE←ILEFT≤IBOUNDARY; ICOMPARE←ILEFT≥IBOUNDARY;
03700 ICOMPARE←¬EQU(LEFT,BOUNDARY) END ;
03800 RELOP ← TRYFAMILY(RELQ) ELSE IF RELOP < 0 THEN -1 ELSE -2 ;
03900 LEFT ← BOUNDARY ; ILEFT ← IBOUNDARY ;
04000 END "COMPARATORS" UNTIL RELOP < 0 ;
04100 COMPARE ← IF RELOP=-1 THEN BOUNDARY ELSE CVS(ICOMPARE) ;
04200 IF NOTOP = 0 THEN COMPARE ← IF TRUESTR(COMPARE) THEN "0" ELSE "-1" ;
04300 NOTOP ← -1 ;
04400 IF ANDOP < 0 OR TRUESTR(ALL) THEN IF FALSTR(ALL ← COMPARE) THEN ON ← FALSE ;
04500 ANDOP ← TRYFAMILY(ANDQ) ELSE -1 ; ALL ← ALL ; comment SAIL bug -- force it to store;
04600 END "CONJUNCTS" UNTIL ANDOP < 0 ;
04700 ON ← WASONA ;
04800 IF OROP < 0 OR FALSTR(ANY) THEN IF TRUESTR(ANY ← ALL) THEN ON ← FALSE ;
04900 OROP ← TRYFAMILY(ORQ) ELSE -1 ; ANY ← ANY ; comment SAIL bug -- force it to store ;
05000 END "DISJUNCTS" UNTIL OROP < 0 ;
05100 ON ← WASONO ;
05200 RETURN(DUMMYSTR ← ANY) ; comment, DUMMYSTR due to SAIL RECURSIVE STRING PROCEDURE bug (see DCS);
05300 END "SIMPLE EXPRESSION" ;
00100 STRING SIMPLE PROCEDURE DEFN(BOOLEAN SUBSTVARIABLES,FORFILE; INTEGER ARGS, IBASE) ;
00200 BEGIN
00300 STRING SEGMENT, IDENT, PSPCS, SPCS, FML, TXID, TX2 ; INTEGER SINDX, I, DEEP ; LABEL FORMAL ;
00400 IF ITSCH(;) THEN PASS ; DEFINING ← NOT FORFILE ; comment, makes RD include line nos in result ;
00500 IF ¬ITSCH(⊂) AND NOT(ITSCH($) AND NEXTSCH("("))
00600 THEN BEGIN WARN("=","Missed ⊂ OR $( in definition") ; RETURN(NULL) END ;
00700 DEEP ← 1 ; SINDX ← SHIGH ;
00800 IF SHIGH+20>STSIZE THEN
00900 BEGIN
01000 SGROW(STBL,STBLIDA,STSIZE,100,"Definition") ;
01100 SMAKEBE(STBLIDA, STBL) ; ZEROSTRINGS(100, STBL[STSIZE-99]) ;
01200 END ;
01300 EMPTYTHIS ; comment For page label switch in LABELREF ;
01400 IF FORFILE THEN STBL[SINDX←SINDX+1] ← SRCLINE & "/" & SRCPAGE & TB & ALTMODE ;
01500 IF EQU(INPUTSTR[1:2], RCBRAK&VT) THEN
01600 BEGIN
01700 STBL[SINDX ← SINDX + 1] ← CRLF & SRCLINE & "/" & SRCPAGE & TB ;
01800 INPUTSTR ← INPUTSTR[3:∞] ;
01900 END ;
02000 WHILE DEEP DO
02100 BEGIN "DEF BODY"
02200 SEGMENT ← RD(DEFN!TABLE) ;
02300 IF BRC = "⊂" ∨ BRC="$"∧INPUTSTR="("∧LOP(INPUTSTR)="(" THEN
02400 BEGIN DEEP ← DEEP + 1 ; SEGMENT ← SEGMENT & "⊂" ; END
02500 ELSE IF BRC = "⊃" ∨ BRC=")"∧INPUTSTR="$"∧LOP(INPUTSTR)="$" THEN
02600 BEGIN DEEP ← DEEP - 1 ;
02700 SEGMENT ← SEGMENT & (IF DEEP THEN "⊃" ELSE SP) ;
02800 END
02900 ELSE IF BRC = "∃" THEN SEGMENT ← SEGMENT & (IF DEEP>1 THEN BRC ELSE NULL) & RD(ONE!CHAR)
03000 ELSE IF LENGTH(TXID←BRC) ∧
03100 (LDB(SPCODE(BRC))=LCURLY ∨
03200 LDB(SPCODE(BRC))=DOLLAR ∧ LDB(SPCODE(INPUTSTR))=LBRACK ∧
03300 LENGTH(TXID←TXID&LOP(INPUTSTR))) THEN
03400 IF SUBSTVARIABLES THEN
03500 BEGIN "{..."
03600 SPCS ← TXID & RD(TO!VISIBLE) ;
03700 IDENT ← SCAN(INPUTSTR,ALPHA,DUMMY) ; PSPCS ← RD(TO!VISIBLE) ;
03800 IF BRC = RCBRAK ∨ BRC="]"∧INPUTSTR[2 FOR 1]="$"THEN
03900 BEGIN
04000 LOPP(INPUTSTR) ;
04100 IF BRC="]" THEN BEGIN TX2←"]$" ; LOPP(INPUTSTR) END ELSE TX2←RCBRAK ;
04200 SEGMENT ← SEGMENT &
04300 (IF FULSTR(IDENT) ∧ SIMLOOK(CAPITALIZE(IDENT))
04400 AND SYMTYPE<MACROTYPE THEN TES 11/29/73 ;
04500 IF SYMIX=IXPAGE THEN ALTMODE&"[@]"&
04600 LABELREF(0,
04700 IF SYMBOL=SYMPAGE THEN CTR!CHRS(IXPAGE)
04800 ELSE PATT!CHRS(IXPAGE))
04900 ELSE EVALV(IDENT, SYMIX, SYMTYPE)
05000 ELSE SPCS & IDENT & PSPCS & TX2)
05100 END
05200 ELSE SEGMENT ← SEGMENT & SPCS & IDENT & PSPCS ;
05300 END "{..."
05400 ELSE SEGMENT ← SEGMENT & TXID
05500 ELSE IF BRC = RCBRAK THEN
05600 IF EQU(INPUTSTR[1:2], RCBRAK&VT) THEN ELSE SEGMENT ← SEGMENT & BRC
05700 ELSE IF LDB(FAMILY(BRC)) = LETTQ THEN
05800 BEGIN "LETTER"
05900 IDENT ← (BRC+0) & SCAN(INPUTSTR, ALPHA, BRC) ;
06000 FOR I ← 1 THRU ARGS DO IF EQU(FML←SYM[ITBL[IBASE+I]], TXID←CAPITALIZE(IDENT)) THEN
06100 FORMAL: BEGIN IDENT ← VT & I ; DONE END
06200 ELSE IF 1 ≤ LENGTH(TXID)-LENGTH(FML) ≤ 2 THEN
06300 BEGIN "MAYBE UNDERLINED"
06400 INTEGER L, R ;
06500 L ← IF TXID="!" THEN 1 ELSE 0 ; R ← IF TXID[∞ FOR 1]="!" THEN 1 ELSE 0 ;
06600 IF EQU(FML, TXID[1+L TO ∞-R]) THEN
06700 BEGIN
06800 IF L THEN SEGMENT ← SEGMENT & "!" ;
06900 IF R THEN INPUTSTR ← "!" & INPUTSTR ;
07000 GO TO FORMAL ;
07100 END ;
07200 END "MAYBE UNDERLINED" ;
07300 SEGMENT ← SEGMENT & IDENT ;
07400 END "LETTER"
07500 ELSE SEGMENT ← SEGMENT & BRC ;
07600 STBL[SINDX ← SINDX+1] ← SEGMENT ;
07700 IF SINDX = SHIGH+20 THEN
07800 BEGIN
07900 SEGMENT ← STBL[SHIGH + 1] ;
08000 FOR I ← SHIGH + 2 THRU SINDX DO BEGIN SEGMENT ← SEGMENT & STBL[I] ; STBL[I]←NULL; END;
08100 SINDX ← SHIGH + 1 ; STBL[SINDX] ← SEGMENT ;
08200 END ;
08300 END "DEF BODY" ;
08400 SEGMENT ← STBL[SHIGH+1] ; FOR I ← SHIGH+2 THRU SINDX DO SEGMENT ← SEGMENT & STBL[I] ;
08500 IF FORFILE THEN SEGMENT ← SEGMENT & LF ;
08600 DEFINING ← FALSE ; INPUTSTR ← ";" & INPUTSTR ; PASS ;
08700 RETURN(SEGMENT) ;
08800 END "DEFN" ;
00100 RECURSIVE PROCEDURE PARAMS(INTEGER MOST; STRING ARRAY PRE,PAR,POST);
00200 BEGIN comment, Reads arguments for various commands;
00300 INTEGER I, PREWD, SOFAR ; STRING EXPR ;
00400 LABEL RDPAR, SETPAR ;
00500 BOOLEAN GOT ; DEFINE FIND = "FOR I ← 1 THRU MOST DO IF" ;
00600 SOFAR ← I ← GOT ← 0 ;
00700 WHILE SOFAR<MOST ∧ THISTYPE≠-TERQ ∧ THISTYPE≠MANTYPE DO
00800 BEGIN "PARAMETER"
00900 IF THISISID THEN
01000 BEGIN "IDENTIFIER"
01100 IF ITS(TO) ∧ I<MOST ∧ ITSV(PRE[I+1]) THEN BEGIN PASS; I←I+1; GO TO RDPAR END;
01200 FIND ITSV(PRE[I]) ∨ ITSV(PRE[I]&"S") THEN
01300 BEGIN "PRE WORD"
01400 PASS ; IF GOT LAND TWO(I) THEN WARN("=",PRE[I]&" Twice") ;
01500 GO TO RDPAR ;
01600 END "PRE WORD" ;
01700 END "IDENTIFIER" ;
01800 FIND ¬GOT LAND TWO(I) ∧ NULSTR(PRE[I]) ∧ (I=1 ∨ NULSTR(PRE[I-1]) ∨ GOT LAND TWO((I-1))) THEN GO TO RDPAR ;
01900 DONE ;
02000 RDPAR:
02100 PREWD ← I ;
02200 EXPR ← IF EQU(PRE[I],"IN") ∧ FULSTR(PAR[I]) THEN SPASS(THISWD) comment COUNT...IN -- ;
02300 ELSE IF ITSCH(⊂) THEN 0 & DEFN(FALSE, FALSE, 0, 0)
02400 ELSE E(NULL,IF I=MOST∨FULSTR(POST[I]) THEN POST[I] ELSE PRE[I+1]) ;
02500 IF FULSTR(POST[I]) THEN
02600 IF ITSV(POST[I]) THEN PASS
02700 ELSE BEGIN "GUESSED WRONG"
02800 FIND ITSV(POST[I]) THEN BEGIN PASS ; GO TO SETPAR END ;
02900 FIND NULSTR(POST[I]) THEN GO TO SETPAR ;
03000 WARN("=",POST[PREWD] & "Missed.") ;
03100 DONE ;
03200 END "GUESSED WRONG" ;
03300 SETPAR:
03400 IF PRE[I]≠PRE[PREWD] THEN WARN("=",(IF FULSTR(POST[PREWD]) THEN POST[PREWD] ELSE PRE[I])& " Missed.") ;
03500 IF GOT LAND TWO(I) THEN WARN("=","Duplicate Parameter "&PRE[I]&SP&EXPR&SP&POST[I])
03600 ELSE SOFAR ← SOFAR + 1 ;
03700 GOT ← GOT LOR TWO(I) ;
03800 PAR[I] ← EXPR ;
03900 IF ITSCH(",") THEN PASS ;
04000 END "PARAMETER" ;
04100 END "PARAMS" ;
04200
04300 RECURSIVE STRING PROCEDURE SIMPAR ;
04400 RETURN(IF THISISCON THEN THISWD[2 TO ∞] ELSE IF THISISID THEN VEVAL ELSE NULL) ;
00100 SIMPLE PROCEDURE FINPORTION ;
00200 BEGIN
00300 DBREAK ;
00400 IF OLDPGIDA THEN NEXTPAGE ;
00500 END "FINPORTION" ;
00600
00700 RECURSIVE PROCEDURE DAREA(BOOLEAN TITAREA) ;
00800 BEGIN
00900 INTEGER I, IX, SYMB, TEMP, A, B ;
01000 PRELOAD!WITH "LINE", "TO", "CHAR", "TO", "IN", "COLUMN", "COLUMN" ;
01100 OWN STRING ARRAY PRE[1:7] ; STRING ARRAY PAR[1:7] ;
01200 PRELOAD!WITH NULL, NULL, NULL, NULL, NULL, "WIDE", "APART" ;
01300 OWN STRING ARRAY POST[1:7] ;
01400 DBREAK; DPASS ;
01500 IF ¬THISISID THEN BEGIN WARN("=","AREA MUST HAVE NAME"); THISWD←"!DUMMY" END ;
01600 SYMB ← SYMNUM(THISWD) ;
01700 PASS ;
01800 PARAMS(7, PRE, PAR, POST) ;
01900 IF ¬ON THEN RETURN ;
02000 BIND(DECLARE(SYMB, AREATYPE), IX←PUSHI(AREAWDS,AREATYPE)) ;
02100 IF FULHIGH(IX)←NULSTR(PAR[1]) THEN BEGIN A←1 ; B←FHIGH END comment assume LINE 1 TO <frame height> ;
02200 ELSE BEGIN A ← CVD(PAR[1]) ; B ← IF NULSTR(PAR[2]) THEN A ELSE CVD(PAR[2]) END ;
02300 LINE1(IX) ← A MAX 1 ; LINECT(IX) ← B-A+1 MAX 1 ;
02400 IF FULWIDE(IX)← NULSTR(PAR[3]) THEN BEGIN A←1 ; B←FWIDE END
02500 ELSE BEGIN A ← CVD(PAR[3]) ; B ← IF NULSTR(PAR[4]) THEN A ELSE CVD(PAR[4]) END ;
02600 CHAR1(IX) ← A MAX 1 ; CHARCT(IX) ← B←B-A+1 MAX 1 ;
02700 TEXTAR(IX) ← IF TITAREA THEN 0 ELSE 1 ;
02800 IF NULSTR(PAR[5]) THEN A ← 1 comment Assume IN 1 COLUMNS <charct> WIDE ;
02900 ELSE BEGIN "COLUMNS"
03000 A ← CVD(PAR[5]) ; comment How many ;
03100 IF FULSTR(PAR[6]) THEN B ← CVD(PAR[6]) MIN B DIV A
03200 ELSE B ← (B+( TEMP←IF FULSTR(PAR[7]) THEN CVD(PAR[7]) ELSE 5 )) DIV A - TEMP ;
03300 END "COLUMNS" ;
03400 COLCT(IX) ← A MAX 1 ; COLWID(IX) ← B MAX 1 ;
03500 OLMAX ← OLMAX + A*LINECT(IX) ;
03600 FOOTSTR(IX) ← PUSHS(1, NULL) ;
03700 MARGINS(IX) ← FONTS(IX) ← 0 ; TES 11/15/73 ;
03800 TFONT(IX) ← OFONT(IX) ← DEFAULTFONT ; TES 11/15/73 ;
03900 END "DAREA" ;
00100 SIMPLE PROCEDURE DBELOW ;
00200 BEGIN
00300 END "DBELOW" ;
00400
00500 RECURSIVE PROCEDURE DBLANKPAGE ;
00600 BEGIN COMMENT LEAVE N BLANK PAGES WITHOUT AFFECTING THE PAGE NUMBER ;
00700 INTEGER I, J, N ;
00800 PASS ; N ← CVD(E("1", NULL)) ;
00900 IF ¬ON THEN RETURN ;
01000 DBREAK ;
01100 IF OLDPGIDA THEN NEXTPAGE ;
01200 IF INTER ≤ 0 THEN NOPORTION ;
01300 FOR I ← 1 THRU N DO FOR J ← PHIGH, PWIDE, -10 DO WORDOUT(INTER, J) ;
01400 END ;
01500
01600 SIMPLE PROCEDURE DCC ;
01700 BEGIN
01800 END "DCC" ;
01900
02000 RECURSIVE PROCEDURE DCLOSE ;
02100 BEGIN
02200 DBREAK ; PASS ;
02300 IF ON THEN
02400 IF THISTYPE=AREATYPE THEN CLOSEAREA(IX,FALSE)
02500 ELSE IF IX=IXPAGE THEN comment, * * * * * * * * * * * * * ;
02600 ELSE WARN("=","CLOSE What? "&SOMEINPUT) ;
02700 PASS ;
02800 END "DCLOSE" ;
02900
03000 SIMPLE PROCEDURE DCOMMANDCHARACTER ;
03100 BEGIN
03200 INTEGER X ;
03300 INPUTSTR ← ";;" & INPUTSTR ; COMMENT couple extra semicolons to assure next line read right ;
03400 PASS ; X ← SIMPAR ;
03500 IF LENGTH(X) ≠ 1 THEN WARN("=","COMMAND CHARACTER must be a single character, not `"&X&"'")
03600 ELSE IF ON THEN COMMAND!CHARACTER ← X ;
03700 PASS ; PASS ; PASS ;
03800 END "DCOMMANDCHARACTER" ;
03900
04000 SIMPLE PROCEDURE DCOUNT ;
04100 BEGIN
04200 INTEGER USYMB, INLINE ;
04300 PRELOAD!WITH "FROM", "TO", "BY", "IN", "PRINTING" ;
04400 OWN STRING ARRAY PRE[1:5] ; OWN STRING ARRAY PAR[1:5] ;
04500 DPASS ; IF ¬THISISID THEN BEGIN WARN("=","Unit must have a name") ; THISWD ← "!DUMMY" END ;
04600 USYMB ← SYMNUM(THISWD) ; PASS ; IF ITS(INLINE) THEN BEGIN INLINE←TRUE; PASS END ELSE INLINE←FALSE ;
04700 PAR[1]←PAR[2]←PAR[3]←PAR[5]←NULL;
04800 PAR[4] ← 0 ; PARAMS(5, PRE, PAR, NULLS) ;
04900 IF ON THEN CREUNIT( INLINE,
05000 IF NULSTR(PAR[1]) THEN 1 ELSE CVD(PAR[1]), comment, FROM -- ;
05100 IF NULSTR(PAR[2]) THEN 18 ELSE CVD(PAR[2]), comment, TO -- ;
05200 IF NULSTR(PAR[3]) THEN 1 ELSE CVD(PAR[3]), comment, BY -- ;
05300 IF PAR[4] = 0 THEN 0 ELSE SYMNUM(PAR[4]), comment IN -- ;
05400 IF NULSTR(PAR[5]) THEN "1" ELSE PAR[5], comment, PRINTING -- ;
05500 USYMB ) ;
05600 END "DCOUNT" ;
05700
05800 SIMPLE PROCEDURE DDEVICE ;
05900 BEGIN PASS ;
06000 IF DEVICE ≥ 0 THEN COMMENT IF <0, WAS SET BY /SWITCH, WHICH TAKES PRECEDENCE ;
06100 IF ITS(MIC) THEN DEVICE←MIC ELSE IF ITS(TTY) THEN DEVICE←TTY
06200 ELSE IF ITS(LPT) THEN DEVICE←LPT
06300 ELSE IF ITS(XGP) THEN BEGIN DEVICE ← XGP; XCRIBL ← TRUE; OUTSTR(" XCRIBL!"); END
06400 ELSE WARN("=","No such device: "&THISWD) ;
06500 PASS ;
06600 END "DDEVICE" ;
06700
06800 SIMPLE PROCEDURE DDONE ;
06900 BEGIN TES 8/14/74 ;
07000 INTEGER B ;
07100 PASS ;
07200 IF ON THEN
07300 IF REPEATS=0 THEN WARN(NULL,"IGNORED A DONE WITHOUT A REPEAT")
07400 ELSE
07500 BEGIN
07600 REPEATS ← REPEATS - 1 ;
07700 EMPTYTHIS ; EMPTYTHAT ; INPUTSTR ← NULL ;
07800 WHILE CHANSCAN(LAST) > -2 AND LAST DO
07900 INPUTSTR ← SWICHBACK ;
08000 B ← -2 - CHANSCAN(LAST) ;
08100 STRSCAN(LAST) ← NULL ;
08200 WHILE B<BLNMS DO
08300 CASE IF STARTS THEN 0 ELSE ENDCASE OF
08400 BEGIN
08500 BEGIN BLNMS←BLNMS-1 ; STARTS←STARTS-1 ; END ;
08600 BEGIN BLNMS←BLNMS-1 ; IF ENDBLOCK THEN WARN("=","MISSED END") END ;
08700 IF ENDBLOCK THEN WARN("=", "MISSED END") ELSE
08800 BEGIN BLNMS←BLNMS-1 ; IF ENDBLOCK THEN WARN("=","MISSED END") END ;
08900 BEGIN BLNMS←BLNMS-1 ; IF ENDBLOCK THEN MYEND ← TRUE ELSE WARN("=","EXTRA END") END ;
09000 END ;
09100 CHANSCAN(LAST) ← -1 ;
09200 INPUTSTR ← SWICHBACK ;
09300 PASS ;
09400 END ;
09500 END "DDONE" ;
00100 RECURSIVE PROCEDURE DCONDITIONAL ;
00200 BEGIN
00300 BOOLEAN WASON ;
00400 WASON ← ON ; PASS ; ON ← TRUESTR("E(NULL,""THEN"")") ∧ WASON ;
00500 IF ITS(THEN) THEN PASS ELSE WARN("=","Missed THEN in conditional statement") ;
00600 IF STATEMENT THEN BEGIN ON←TRUE; RETURN END; TES 8/14/74 DONE FROM REPEAT ;
00700 IF ITS(ELSE) THEN BEGIN ON←WASON∧¬ON; PASS ; IF STATEMENT THEN BEGIN ON←TRUE; RETURN END END ;
00800 ON ← WASON ;
00900 END "DCONDITIONAL" ;
01000
01100 INTERNAL SIMPLE PROCEDURE READFONT(INTEGER WHICH; STRING FILENAME, BFILENAME) ;
01200 IF ON THEN
01300 BEGIN "READFONT"
01400 INTEGER SAVCW, CHAN, ZILCH, EOF;
01500 IFC TENEX THENC STRING ELSEC INTEGER ENDC NAME, EXT, PPN ;
01600 STRING XFILENAME ;
01700 LABEL TRYAGAIN ; COMMENT SAIL DEFFICIENCY ;
01800 IF NULSTR(BFILENAME) THEN
01900 IFC TENEX THENC
02000 BEGIN
02100 NAME←CVFIL(FILENAME,EXT,PPN) ;
02200 XFILENAME ← NAME & EXT ;
02300 END
02400 ELSEC
02500 XFILENAME ← FILENAME TES 1/22/74 ;
02600 ENDC
02700 ELSE XFILENAME ← BFILENAME ;
02800 SAVCW ← WHATIS(CW);
02900 IF FONTFIL[WHICH] = 0 THEN FONTFIL[WHICH] ← CREATE(0,127);
03000 DUMMY ← FONTFIL[WHICH] ;
03100 IF SAVCW=WCW AND WHICH=DEFAULTFONT THEN SAVCW←DUMMY;
03200 MAKEBE(DUMMY,CW);
03300 OPEN(CHAN←GETCHAN,"DSK",'14, 2,0,0,ZILCH,EOF);
03400 IFC TENEX THENC
03500 LOOKUP(CHAN, FILENAME, FLAG) ;
03600 IF FLAG THEN
03700 BEGIN "HUNTFONT"
03800 ENDC
03900 TRYAGAIN: NAME←CVFIL(FILENAME,EXT,PPN);
04000 WHILE TRUE DO
04100 BEGIN "LKUPLOOP"
04200 IF XLOOKUP(CHAN,NAME,EXT,0,PPN) THEN DONE;
04300 IF EXT=0 THEN EXT←FONTEXT ELSE
04400 IF PPN=0 THEN PPN←FONTPPN ELSE
04500 IF FULSTR(BFILENAME) AND NOT EQU(FILENAME,BFILENAME) THEN
04600 BEGIN
04700 FILENAME ← BFILENAME ;
04800 GO TRYAGAIN ;
04900 END ELSE
05000 BEGIN "NOTFOUND"
05100 OUTSTR("Font file " & FILENAME & " not found. Read file: ");
05200 IFC TENEX THENC
05300 RELEASE(CHAN);
05400 CHAN ← OPENFILE(NULL,"ROC") ;
05500 DONE ;
05600 ELSEC
05700 FILENAME ← INCHWL ;
05800 GO TRYAGAIN ;
05900 ENDC
06000 END "NOTFOUND";
06100 END "LKUPLOOP";
06200 IFC TENEX THENC
06300 END "HUNTFONT" ;
06400 ENDC
06500
06600 IFC VERSION=ITSVER THENC PJ 5/28/74 ;
06700 WORDIN(CHAN);
06800 FNTINF[WHICH]←WORDIN(CHAN);
06900 IF WHICH=DEFAULTFONT THEN BASELINE←LDB(POINT(9,FNTINF[WHICH],17));
07000 FNTINF[WHICH]←LDB(POINT(18,FNTINF[WHICH],35)); ie HEIGHT;
07100 WHILE NOT EOF DO
07200 IF (WORDIN(CHAN) LAND 1) THEN
07300 BEGIN
07400 DUMMY←LDB(POINT(18,DUMMY←WORDIN(CHAN),35));
07500 CW[DUMMY]←LDB(POINT(18,CW[DUMMY]←WORDIN(CHAN),35));
07600 END
07700 ENDC
07800 IFC VERSION=CMUVER THENC
07900 WORDIN(CHAN);
08000 FNTINF[WHICH]←WORDIN(CHAN); COMMENT RKJ 10-10-73;
08100 WHILE NOT EOF DO
08200 IF (WORDIN(CHAN) LAND 1) THEN
08300 BEGIN DUMMY←WORDIN(CHAN); CW[DUMMY]←WORDIN(CHAN) END
08400 ENDC
08500 IFC VERSION=SAILVER THENC
08600 ARRYIN(CHAN,CW[0],128);
08700 FOR I ← 0 THRU 127 DO CW[I] ← CW[I] LSH -18;
08800 WORDIN(CHAN); FNTINF[WHICH]←WORDIN(CHAN);
08900 WORDIN(CHAN);
09000 IF WHICH=DEFAULTFONT THEN BASELINE←WORDIN(CHAN);
09100 ENDC
09200 IFC VERSION=PARCVER THENC
09300 BEGIN
09400 EXTERNAL INTEGER GOGTAB;
09500 INTEGER K,I;
09600 IFC TENEX THENC
09700 DEFINE JSYS="'104000000000", SFBSZ="JSYS '46";
09800 K ← CVJFN(CHAN) ;
09900 START!CODE "BYTE16"
10000 MOVE 1,K; MOVEI 2,16; SFBSZ ;
10100 END "BYTE16" ;
10200 ELSEC
10300 START!CODE "BYTE16" MOVE 1,GOGTAB; ADD 1,CHAN; MOVE 1,'13(1); comment now we have pointer to cdb;
10400 HRRZ 1,2(1); comment now pointer to IBUF;
10500 HRLI 2,'442000;
10600 HLLM 2,1(1);
10700 END "BYTE16";
10800 ENDC
10900 K←WORDIN(CHAN); WORDIN(CHAN);
11000 FNTINF[WHICH]←WORDIN(CHAN); WORDIN(CHAN);
11100 FOR I←1 THRU K DO WORDIN(CHAN);
11200 K←(K MIN 128)-1;
11300 FOR I←0 THRU K DO CW[I]←WORDIN(CHAN);
11400 END;
11500 ENDC;
11600
11700 IFC VERSION=SAILVER THENC CMDFILE ← CMDFILE & "/FONT#" & CVS(WHICH-1) & "=" & FILENAME ENDC;
11800 TES 1/7/74 ADDED NEXT LINE: ; TES 1/22/74 PUT XFILENAME ;
11900 FNTNAME[WHICH]←XFILENAME; HIFONT←WHICH MAX HIFONT ;
12000 RELEASE(CHAN);
12100 MAKEBE(SAVCW,CW);
12200 END "READFONT";
00100 INTERNAL SIMPLE PROCEDURE SWITCHFONT(INTEGER WHICH) ;
00200 BEGIN TES 11/15/73 TO DO IT BY AREA ;
00300 INTEGER NEWIX ;
00400 IF AREAIXM AND FONTS(AREAIXM) < OLDIHED THEN
00500 BEGIN TES FIRST CHANGE IN THIS BLOCK IN THIS AREA ;
00600 NEWIX ← PUSHI(FONTWDS, FONTYPE) ;
00700 AREAX(NEWIX) ← AREAIXM ;
00800 OUTERX(NEWIX) ← FONTS(AREAIXM) ;
00900 THISFONTX(NEWIX) ← THISFONT ;
01000 OLDFONTX(NEWIX) ← OLDFONT ;
01100 FONTS(AREAIXM) ← NEWIX ;
01200 END ;
01300 OLDFONT ← THISFONT;
01400 IF THISFONT NEQ WHICH THEN
01500 BEGIN
01600 THISFONT ← WHICH;
01700 WHICH ← FONTFIL[WHICH]; MAKEBE(WHICH,CW);
01800 END ;
01900 END ;
02000
02100 INTERNAL SIMPLE PROCEDURE SELECTFONT(INTEGER WHICH);
02200 IF ON THEN
02300 BEGIN "SELECTFONT"
02400 INTEGER F;
02500 DBREAK;
02600 IF NOT XCRIBL OR LAST<4 THEN RETURN;
02700 F←(IF WHICH<10 THEN (WHICH+"0") ELSE (WHICH+("A"-10)));
02800 IF FONTFIL[WHICH]=0 THEN BEGIN WARN("=","Unknown font `"& F & "'");
02900 RETURN END;
03000 SWITCHFONT(WHICH) ; TES 11/14/73 SUBROUTINIZED ;
03100 TES 11/15/73 erased: XGPCMD ← (FONTCHAR & "F") & F ;
03200 END "SELECTFONT";
03300
03400 INTERNAL SIMPLE INTEGER PROCEDURE RFONT(INTEGER F) ;
03500 RETURN( TES SUBROUTINIZED AND CASED 11/29/73 ;
03600 IFC VERSION = SAILVER OR VERSION=ITSVER PJ 5/28/74 ; THENC
03700 IF "1"≤F≤"9" THEN F←F-"0"
03800 ELSE IF "A"≤F≤"Z" THEN F←F-("A"-10)
03900 ELSE IF "a"≤F≤"z" THEN F←F-("a"-10)
04000 ELSE -1
04100 ENDC
04200 IFC VERSION = PARCVER THENC
04300 IF "1"≤F≤"9" THEN F←F-"0"
04400 ELSE -1
04500 ENDC
04600 IFC VERSION = CMUVER THENC
04700 IF "A"≤F≤"B" THEN F←F-("A"-10)
04800 ELSE IF "a"≤F≤"b" THEN F←F-("a"-10)
04900 ELSE IF "1"≤F≤"2" THEN F←F-"0"
05000 ELSE -1
05100 ENDC
05200 ) ;
05300
05400 SIMPLE PROCEDURE DFONT(BOOLEAN SELECT);
05500 BEGIN "DFONT"
05600 INTEGER F;
05700 PASS;
05800 IF LENGTH(THISWD)=1 AND THISTYPE GEQ 0 AND (F←RFONT(THISWD)) GEQ 0 THEN PASS
05900 ELSE F ← RFONT(E(NULL,NULL)) ; TES 11/29/73 ;
06000 IF F<0 THEN
06100 BEGIN WARN("=","Illegal font `"&F&"'"); RETURN END;
06200 IF SELECT THEN SELECTFONT(F) TES 1/22/74 ADDED OPTIONAL XGP FILENAME ;
06300 ELSE READFONT(F,E(NULL,NULL), IF ITSCH(",") THEN PASS&E(NULL,NULL) ELSE NULL);
06400 END "DFONT";
00100 RECURSIVE PROCEDURE DFRAME(BOOLEAN BOXFRM) ;
00200 BEGIN
00300 INTEGER L, I ;
00400 PRELOAD!WITH "HIGH", "WIDE" ; OWN STRING ARRAY POST[1:2];
00500 STRING ARRAY PAR[1:2] ;
00600 DAPART ; PASS ; PARAMS(2,NULLS,PAR,POST);
00700 IF ON THEN
00800 IF BOXFRM THEN BEGIN END
00900 ELSE
01000 BEGIN
01100 PHIGH←FHIGH←IF NULSTR(PAR[1]) THEN 1 ELSE CVD(PAR[1]) ;
01200 PWIDE←FWIDE←IF NULSTR(PAR[2]) THEN 1 ELSE CVD(PAR[2]) ;
01300 IF OLDPGIDA THEN NEXTPAGE ;
01400 L ← NULLAREAS ;
01500 WHILE L DO BEGIN
01600 I ← AREAIDA ; IDASSIGN(AREAIDA←L,THISAREA) ; L ← RH(INA) ;
01700 OPEN!ACTIVE(DEFA) ← 0 ; GOAWAY(AREAIDA) ; IF (AREAIDA←I) THEN IDASSIGN(AREAIDA,THISAREA) ;
01800 END ;
01900 NULLAREAS ← 0 ;
02000 END ;
02100 END "DFRAME" ;
02200
02300 SIMPLE PROCEDURE DINDENT ;
02400 BEGIN
02500 STRING X ;
02600 DBREAK ; PASS ; X ← E(NULL,NULL) ; IF ON ∧ FULSTR(X) THEN FIRSTIM ← CVD(X) ;
02700 IF ITSCH(",") THEN BEGIN PASS ; X←E(NULL, NULL) END ELSE X←NULL ;
02800 IF ON ∧ FULSTR(X) THEN RESTIM←CVD(X) ;
02900 IF ITSCH(",") THEN BEGIN PASS ; X←E(NULL, NULL) END ELSE X←NULL ;
03000 IF ON ∧ FULSTR(X) THEN RIGHTIM←CVD(X) ;
03100 END "DINDENT" ;
00100 SIMPLE PROCEDURE DINSERT ;
00200 BEGIN
00300 INTEGER CHAN, PIX, ROTTEN ;
00400 IF ON THEN BEGIN TES 4/11/74;
00500 FINPORTION ;
00600 IF INTER ≥ 0 THEN
00700 BEGIN FOR DUMMY←1 THRU 5 DO WORDOUT(INTER,-20) ; RELEASE(INTER) ; RELEASE(SINTER) ; SINTER←INTER←-1 END ;
00800 END ;
00900 DO BEGIN "COLLATE"
01000 DPASS ; IF ¬THISISID THEN BEGIN WARN("=","Unnamed INSERT Portion!") ; RETURN END ;
01100 IF ON THEN
01200 BEGIN ROTTEN ← FALSE ;
01300 IF THISTYPE ≠ PORTYPE THEN
01400 BEGIN
01500 BIND(SYMB←DECLARE(SYMB, PORTYPE), PIX ← PUTI(4, -5));
01600 PORSTR(PIX) ← PUTS(NULL) ; PUTS(NULL) ; TES 3/21/74;
01700 END
01800 ELSE IF (CHAN ← PORCH(PIX ← IX)) = -1 THEN BEGIN WARN("=","Can't INSERT FOOT!"); ROTTEN←TRUE END
01900 ELSE IF ¬(0 ≤ CHAN ≤ 15) THEN BEGIN WARN("=","Can't INSERT passed Portion "&THISWD) ; ROTTEN←TRUE END ;
02000 IF ¬ROTTEN THEN BEGIN PORSEQ(SEQPORT) ← PIX ; PORSEQ(SEQPORT ← PIX) ← -1 END ;
02100 PASS ;
02200 END ;
02300 END "COLLATE" UNTIL ¬ITSCH(",") ;
02400 END "DINSERT" ;
02500
02600 SIMPLE PROCEDURE DLET ;
02700 BEGIN
02800 INTEGER LOC ; LABEL BADLET ;
02900 DPASS ; IF THATISID THEN BEGIN THATWD ← THISWD & THATWD ; DPASS END ; LOC ← SYMB ;
03000 IF ¬THISISID THEN GO TO BADLET ; PASS ; IF ¬ITSCH(=) THEN GO TO BADLET ; DPASS ;
03100 IF THISTYPE≠MANTYPE AND THATISID THEN BEGIN THATWD←THISWD&THATWD ; PASS END ;
03200 IF THISTYPE≠MANTYPE THEN GO TO BADLET ; IF ON THEN BIND(LOC←DECLARE(LOC, MANTYPE), IX) ; PASS ;
03300 RETURN ;
03400 BADLET: WARN("=","LET <ID>=<RESWD>, please!") ; DO PASS UNTIL THISISID ∨ THISTYPE=-TERQ ;
03500 END "DLET" ;
03600
03700 SIMPLE PROCEDURE DLOCK ;
03800 BEGIN
03900 END "DLOCK" ;
00100 SIMPLE PROCEDURE DLOCAL ;
00200 DO BEGIN
00300 DPASS ;
00400 IF THISISID THEN
00500 BEGIN
00600 IF ON THEN
00700 BIND(SYMB←DECLARE(SYMB, LOCALTYPE), IX←PUSHS(1,NULL)) ;
00800 PASS ;
00900 END
01000 ELSE BEGIN WARN("=","LOCAL declaration missing identifier"); IF THISTYPE≠TERQ THEN PASS END ;
01100 END UNTIL ¬ITSCH(",") ;
01200
01300 SIMPLE PROCEDURE DMACRO(BOOLEAN ODDONE) ;
01400 BEGIN COMMENT, OLD VERSION NOT GARBAGED BUT COULD BE ;
01500 INTEGER SIHIGH, MIX, ARGS, J, NAMES, NAME ; BOOLEAN ROTTEN ;
01600 SIHIGH ← IHIGH ; DPASS ; IF ¬THISISID THEN BEGIN WARN("=","Macro name not identifier") ; RETURN END ;
01700 IF THATISID THEN BEGIN "TWO WORD" THISWD ← THISWD & SP & THATWD ; RDENTITY ; END "TWO WORD" ;
01800 PUTI(1, SYMNUM(THISWD)) ; PASS ;
01900 IF ITSCH("(") THEN
02000 BEGIN "FORMALS"
02100 ROTTEN ← FALSE ; THISWD ← "," ; NAMES ← 0 ;
02200 DO BEGIN
02300 IF ITSCH(",") THEN DPASS
02400 ELSE BEGIN WARN("=","Missed comma in macro formal list") ; ROTTEN←TRUE END ;
02500 IF ITSCH(ε) THEN BEGIN DPASS ; NAME ← 0 ; END ELSE NAME ← 1 ;
02600 IF ¬THISISID THEN BEGIN WARN("=","Formal parameters must be identifiers") ; ROTTEN←TRUE END
02700 ELSE BEGIN PUTI(1, SYMB) ; NAMES ← 2*NAMES + NAME ; DPASS END ;
02800 END
02900 UNTIL ITSCH(")") ∨ ROTTEN ;
03000 IF ITSCH(")") THEN PASS ;
03100 END "FORMALS" ;
03200 IF ROTTEN ∨ ¬ON THEN BEGIN IHIGH ← SIHIGH ; DEFN(FALSE, FALSE,0,0) ; RETURN END ;
03300 ARGS ← IHIGH - SIHIGH - 1 ; BIND(DECLARE(ITBL[SIHIGH+1], MACROTYPE), MIX←PUSHI(MACROWDS,MACROTYPE)) ;
03400 NUMARGS(MIX) ← ARGS ; ODDMAC(MIX) ← ODDONE ; BODY(MIX) ← PUSHS(1,DEFN(FALSE, FALSE,ARGS,SIHIGH+1)) ;
03500 IHIGH ← SIHIGH ; NAMEPAR(MIX) ← NAMES ;
03600 END "DMACRO" ;
00100 SIMPLE PROCEDURE DMARGINS(BOOLEAN INWARD) ;
00200 BEGIN
00300 STRING S ; INTEGER L, R, W, ARIX, OLDIX, NEWIX ;
00400 IF ON THEN DBREAK ;
00500 ARIX ← IF AREAIXM THEN AREAIXM ELSE IXTEXT ; OLDIX ← MARGINS(ARIX) ; PASS ;
00600 S ← IF THISTYPE > INTERNTYPE ∨ THISTYPE=-TERQ ∨ NEXTSCH(←) ∨ NEXTSCH(:) THEN NULL
00700 ELSE E(NULL, NULL) ;
00800 IF FULSTR(S) ∨ ITSCH(",") THEN
00900 BEGIN "HAS PARAMS"
01000 L ← IF FULSTR(S) THEN CVD(S) ELSE 0 ;
01100 IF ITSCH(",") THEN BEGIN PASS ; R ← CVD(E("0",NULL)) END ELSE R ← 0 ;
01200 IF ¬ON THEN RETURN ;
01300 MARGINS(ARIX) ← NEWIX ← PUSHI(MARGWDS, MARGTYPE) ; W ← COLWID(ARIX) ;
01400 LMARG ← (IF OLDIX THEN LMARGX(OLDIX) ELSE 0) + INWARD*L MAX 0 MIN W-1 ;
01500 RMARG ← (IF OLDIX THEN RMARGX(OLDIX) ELSE W) - INWARD*R MIN W MAX LMARG+1 ;
01600 LMARGX(NEWIX) ← LMARG ; RMARGX(NEWIX) ← RMARG ;
01700 AREAX(NEWIX) ← ARIX ; OLD!MARGX(NEWIX) ← OLDIX ;
01800 END "HAS PARAMS"
01900 ELSE IF ¬ON THEN RETURN
02000 ELSE IF OLDIX THEN
02100 BEGIN "UNNEST"
02200 AREAX(OLDIX) ← 0 ; comment, so ENDBLOCK won't use it ;
02300 MARGINS(ARIX) ← NEWIX ← OLD!MARGX(OLDIX) ;
02400 LMARG ← IF NEWIX THEN LMARGX(NEWIX) ELSE 0 ;
02500 RMARG ← IF NEWIX THEN RMARGX(NEWIX) ELSE COLWID(ARIX) ;
02600 IF OLDIX = IHED THEN IHED ← IHED - 1 - MARGWDS ;
02700 END "UNNEST"
02800 ELSE WARN("=","Extra "&(IF INWARD>0 THEN "NARROW" ELSE "WIDEN")&" in Margin Nest") ;
02900 END "DMARGINS" ;
03000
03100 RECURSIVE PROCEDURE DNEXT ;
03200 BEGIN
03300 COMMENT Already PASSed "NEXT" ;
03400 IF ¬THISISID ∨ (THISTYPE ≠ UNITTYPE ∧ THISTYPE ≠ PUNITTYPE) THEN WARN("=","NEXT what?")
03500 ELSE IF ON THEN IF IX=IXPAGE THEN NEXTPAGE ELSE USTEP(SYMB, IX) ;
03600 PASS ;
03700 END "DNEXT" ;
03800
03900 SIMPLE PROCEDURE DPACK ;
04000 BEGIN
04100 END "DPACK" ;
04200
04300 RECURSIVE PROCEDURE DPICHAR ;
04400 BEGIN TES 11/29/73 ;
04500 INTEGER KEY, IX, F, N ; STRING S ;
04600 INPICHAR ← TRUE ;
04700 PASS ;
04800 KEY ←E(NULL,NULL) ;
04900 IF ITSCH("(") THEN
05000 BEGIN COMMENT TURN ON ;
05100 PASS ;
05200 DO S ← S & E(NULL,NULL) UNTIL ITSCH(")") ;
05300 PASS ;
05400 IF ITS(WIDTH) THEN
05500 BEGIN PASS ;
05600 IF ITS(OF) THEN BEGIN PASS ; F←'177; N←CVD(E(NULL,NULL)) END
05700 ELSE BEGIN F←CVD(E(NULL,NULL)); N←F MOD '177; F←F DIV '177 END
05800 END
05900 ELSE BEGIN F←'177 ; N ← SP END ;
06000 S ← F & N & S ;
06100 END
06200 ELSE S ← NULL ; COMMENT TURN OFF ;
06300 IX ← PUSHI(PIWDS,PITYPE) ;
06400 PIKEY(IX) ← KEY ; PIVAL(IX) ← PUSHS(1, PICHAR[KEY]) ;
06500 PICHAR[KEY] ← S ;
06600 INPICHAR ← FALSE ;
06700 END "DPICHAR" ;
00100 SIMPLE PROCEDURE DPORTION ;
00200 BEGIN
00300 INTEGER CHAN, PSIX, PIX ; STRING IFIL ; LABEL WASFWD ;
00400 DPASS ; IF ¬THISISID THEN BEGIN WARN("=","Unnamed PORTION!") ; RETURN END ;
00500 IF ¬ON THEN BEGIN PASS ; RETURN END ;
00600 FINPORTION ;
00700 IF THISTYPE ≠ PORTYPE THEN
00800 BEGIN
00900 BIND(SYMB←DECLARE(SYMB, PORTYPE), PIX ← PUTI(4, -2)) ;
01000 PORSTR(PIX) ← PUTS(NULL) ; PUTS(NULL);
01100 PORSEQ(PIX) ← 0 ;
01200 END
01300 ELSE IF 0 ≤ (CHAN ← PORCH(PIX ← IX)) THEN BEGIN RELEASE(CHAN) ; PORCH(PIX) ← -3 ; GO TO WASFWD END
01400 ELSE IF CHAN = -1 THEN BEGIN WARN("=","Can't declare PORTION FOOT!") ; PASS ; RETURN END
01500 ELSE IF CHAN ≠ -5 THEN WARN("=","PORTION "&THISWD&" already declared!")
01600 ELSE IF PORSEQ(THISPORT) ≠ PIX THEN
01700 BEGIN PORCH(PIX) ← -2 ; COMMENT ADDED FEB 6, 1973 ;
01800 WASFWD: BEGIN
01900 IF INTER ≥ 0 THEN
02000 BEGIN FOR DUMMY←1 THRU 5 DO WORDOUT(INTER,-20) ; RELEASE(INTER) ; RELEASE(SINTER) END ;
02100 INTER ← SINTER ← -1 ;
02200 END ;
02300 END ;
02400 IF INTER < 0 THEN
02500 BEGIN
02600 PSIX ← PORSTR(PIX) ;
02700 IFC TENEX THENC
02800 IFIL ← CVS(INTERS←INTERS+1) ; PORINT(PSIX) ← IFIL ;
02900 INTER ← WRITEON(TRUE,IFILENAME&OCTEXT&IFIL) ;
03000 SINTER← WRITEON(FALSE,IFILENAME&TXTEXT&IFIL) ;
03100 ELSEC
03200 IFIL ← "PUI"&CVS(INTERS←INTERS+1) ;
03300 PORINT(PSIX)←IFIL ;
03400 INTER←WRITEON(TRUE,IFIL&PUIEXT) ; SINTER←WRITEON(FALSE,IFIL&"S"&PUIEXT) ;
03500 ENDC
03600 END ;
03700 IF PORSEQ(PIX) = 0 THEN
03800 BEGIN
03900 PORSEQ(SEQPORT) ← PIX ;
04000 SEQPORT ← PIX ;
04100 END ;
04200 THISPORT ← PIX ; PORTS ← PORTS + 1 ;
04300 PASS ;
04400 END "DPORTION" ;
04500
04600 SIMPLE PROCEDURE DRECEIVE ;
04700 BEGIN
04800 STRING A ;
04900 IF THATISCON ∧ 1≤ LENGTH(THATWD)-1 ≤2 THEN BEGIN PASS ; A ← THISWD[2 TO ∞] END
05000 ELSE A ← NULL ;
05100 IF ON THEN RECEIVE(THISPORT, A) ; PASS ;
05200 END "DRECEIVE" ;
05300
05400 SIMPLE PROCEDURE DREPEAT ;
05500 BEGIN TES 8/14/74 ;
05600 STRING BOD ;
05700 PASS ;
05800 BOD ← DEFN(FALSE, FALSE, 0, 0) ;
05900 IF ON THEN
06000 BEGIN
06100 REPEATS ← REPEATS + 1 ;
06200 SWICH(BOD, -2-BLNMS, 0) ;
06300 SWICH(BOD, -1, 0) ;
06350 PASS ;
06400 END ;
06500 END "DREPEAT" ;
00100 SIMPLE PROCEDURE DRESPONSE(INTEGER COMDWD) ;
00200 BEGIN
00300 INTEGER ARGS, SIHIGH, L1, L2, SIG, CLU, VARI, S, A, RIX, J, TYP, XIX, OLDIX ;
00400 STRING PHR, X, BOD ; BOOLEAN ROTTEN, HASBODY ;
00500 SIMPLE PROCEDURE RESPREPL ;
00600 BEGIN
00700 RIX ← PUSHI(RESPWDS, RESPTYPE) ;
00800 NEXT!RESP(RIX) ← LLPOST ; OLD!RESP(RIX) ← LLTHIS ;
00900 END "RESPREPL" ;
01000 ROTTEN ← FALSE ; ARGS ← 0 ; SIHIGH ← IHIGH ;
01100 IF COMDWD = 1 THEN
01200 BEGIN "AT"
01300 PASS ;
01400 IF ITS(PAGEMARK) THEN BEGIN VARI←2 ; CLU←0 ; L1←FF ; SIG←FF ROT -7 ; PASS END
01500 ELSE BEGIN
01600 X ← SIMPAR ; L1 ← X ;
01700 IF NULSTR(X) THEN BEGIN VARI←2 ; CLU←0 ; L1←CR ; SIG←CR ROT -7 ; PASS END
01800 ELSE IF THISWD[1 FOR 1]="0" THEN BEGIN VARI←1 ; CLU←CVD(X) ; PASS END
01900 TES 11/15/73: TEST ABOVE USED TO BE "0" LEQ L1 LEQ "9".
02000 ALSO, TOOK OUT "PHRASE RESPONSE", VARI=0;
02100 ELSE BEGIN VARI ← 2 ; L1 ← X ; SIG ← CVASC(X) ; CLU ← LENGTH(X) ;
02200 DPASS ; A ← 0 ;
02300 WHILE ¬(ITSCH(;) ∨ ITSCH(⊂)) DO
02400 BEGIN
02500 IF ¬THISISID THEN
02600 BEGIN
02700 WARN("=","Argument must be identifier.") ;
02800 ROTTEN←TRUE ;
02900 END ;
03000 S←SYMB ; PASS ; IF LENGTH(X←SIMPAR)≠1 THEN WARN("=","Separator 1 character only");
03100 PUTI(1, S) ; A ← A LSH 7 LOR X ; DPASS ;
03200 END ;
03300 ARGS ← IHIGH - SIHIGH ;
03400 END ;
03500 END ;
03600 END "AT"
03700 ELSE BEGIN
03800 PASS ; IF ¬THISISID THEN BEGIN WARN("=","BEFORE/AFTER need area/unit name") ; ROTTEN←TRUE END
03900 ELSE BEGIN VARI←IF COMDWD THEN 3 ELSE 4; CLU←SYMB; TYP←THISTYPE; XIX←IX; PASS END ;
04000 END ;
04100 BOD ← DEFN(FALSE, FALSE,ARGS,SIHIGH) ; OLDIX ← RIX ← -1 ;
04200 IF ROTTEN ∨ ¬ON THEN BEGIN IHIGH ← SIHIGH ; RETURN END ;
04300 X ← BOD ; SCAN(X, TO!NON!SP, HASBODY) ; IF ¬HASBODY THEN BOD ← NULL ;
00100 CASE VARI-1 MIN 2 OF
00200 BEGIN
00300 ie 0... Phrase TES 11/15/73 removed this case ;
00400 ie 1 ... Inset ;IF FINDINSET(CLU) THEN
00500 IF DEPTH!RESP(LLTHIS) < DEPTH THEN
00600 BEGIN
00700 RESPREPL ;
00800 IF LLPREV<0 THEN LEADRESPS←RIX ELSE NEXT!RESP(LLPREV) ← RIX ;
00900 END
01000 ELSE IF HASBODY THEN OLDIX ← RIX ← LLTHIS TES 11/29/73 OLDIX;
01100 ELSE BEGIN
01200 OLDIX ← LLTHIS ; TES 11/29/73 ;
01300 LLSKIP(LEADRESPS, NEXT!RESP)
01400 END
01500 ELSE BEGIN
01600 RIX←PUSHI(RESPWDS,RESPTYPE) ;
01700 LLINS(LEADRESPS,NEXT!RESP,RIX) ;
01800 END ;
01900 ie 2 ... Signal;BEGIN S ← 0 ; comment Old response of same signal: >0 for outer block, <0 same block;
02000 IF FINDSIGNAL(SIG) THEN
02100 BEGIN
02200 S ← IF DEPTH!RESP(LLTHIS) < DEPTH THEN LLTHIS ELSE -LLTHIS ;
02300 IF S<0 THEN OLDIX ← LLTHIS; TES 11/29/73 ;
02400 LLSKIP(SIGNALD[L1], NEXT!RESP) ; LLTHIS ← LLPOST ;
02500 END ;
02600 IF HASBODY ∨ S > 0 THEN
02700 BEGIN
02800 RIX←PUSHI(SIGWDS,RESPTYPE); SIGNAL(RIX)←SIG ; NUMARGS(RIX) ← ARGS ;
02900 LLINS(SIGNALD[L1], NEXT!RESP, RIX) ; RESP!SEP(RIX) ← A ;
03000 IF S = 0 THEN SIG!BRC ← (SIG LSH -29) & SIG!BRC ; OLD!RESP(RIX) ← S MAX 0;
03100 END ;
03200 IF NULSTR(BOD) ∧ S THEN
03300 BEGIN
03400 X ← NULL ;
03500 WHILE FULSTR(SIG!BRC) ∧ (A ← LOP(SIG!BRC)) ≠ L1 DO X ← X & A ;
03600 SIG!BRC ← X & SIG!BRC ;
03700 END ;
03800 SETBREAK(TEXT!TBL, TEXT!BRC&SIG!BRC, NULL, "IS") ;
03900 END ;
00100 ie 3,4... AFTER/BEFORE area|unit ;
00200 IF FINDTRAN(CLU, VARI) THEN
00300 IF DEPTH!RESP(LLTHIS) < DEPTH THEN
00400 BEGIN
00500 RESPREPL ;
00600 IF LLPREV < 0 THEN WAITRESP←RIX ELSE NEXT!RESP(LLPREV) ← RIX ;
00700 END
00800 ELSE IF HASBODY THEN OLDIX ← RIX ← LLTHIS
00900 ELSE BEGIN
01000 OLDIX ← LLTHIS ; TES 11/29/73 ;
01100 LLSKIP(WAITRESP, NEXT!RESP)
01200 END
01300 ELSE BEGIN
01400 RIX←PUSHI(RESPWDS,RESPTYPE) ;
01500 LLINS(WAITRESP,NEXT!RESP,RIX) ;
01600 END ;
01700 END ;
01800 IF OLDIX GEQ 0 THEN SSTK[BODY(OLDIX)] ← NULL ; TES 11/29/73 GC ;
01900 IF RIX ≥ 0 THEN
02000 BEGIN
02100 CLUE(RIX) ← CLU ; VARIETY(RIX) ← VARI ;
02200 BODY(RIX) ← PUSHS(1,BOD) ; DEPTH!RESP(RIX) ← DEPTH ;
02300 END ;
02400 END "DRESPONSE" ;
02500
02600 SIMPLE PROCEDURE DREQUIRE ;
02700 BEGIN
02800 STRING F ;
02900 PASS ; F ← E(NULL, "SOURCE!FILE") ;
03000 IF ¬EQU(THISWD[1 TO 6],"SOURCE") THEN WARN("=","REQUIRE -- SOURCE!FILE only!") ;
03100 IF FULSTR(F) ∧ ON THEN SWICHF(F) ; PASS ;
03200 END "DREQUIRE" ;
03300
03400 SIMPLE PROCEDURE DSEND ;
03500 BEGIN
03600 INTEGER PIX; STRING FI ;
03700 INTEGER SIMPLE PROCEDURE OPORT ;
03800 BEGIN INTEGER CH ; CH←WRITEON(FALSE,
03900 IFC TENEX THENC IFILENAME&GENEXT&(FI←THISWD) ELSEC
04000 (FI←(CVS(PORTS←PORTS+1)&THISWD)[1 TO 5])&PUGEXT ENDC) ;
04100 RETURN(CH) ; END "OPORT" ;
04200 PASS ; IF ¬THISISID THEN BEGIN WARN("=","SEND Where?") ; RETURN END ;
04300 IF ¬ON THEN BEGIN PASS ; DEFN(FALSE, FALSE,0,0) ; RETURN END ;
04400 IF THISTYPE ≠ PORTYPE THEN
04500 BEGIN
04600 BIND(SYMB←DECLARE(SYMB, PORTYPE), PIX ← PUTI(4, OPORT) ) ;
04700 PORSTR(PIX) ← PUTS(NULL) ; PUTS(NULL) ;
04800 PORSEQ(PIX) ← 0 ; PORFIL("PORSTR(PIX)") ← FI ;
04900 END
05000 ELSE IF PORCH(PIX←IX)=-5 THEN
05100 BEGIN PORCH(PIX)←OPORT ; PORFIL("PORSTR(PIX)")←FI END ;
05200 PASS ;
05300 SEND(PIX, DEFN(TRUE,PORCH(PIX)≠-1,0,0)) ;
05400 END "DSEND" ;
05500
05600 SIMPLE PROCEDURE DSHOW ;
05700 BEGIN
05800 END "DSHOW" ;
05900
06000 SIMPLE PROCEDURE DSUPERIMPOSE ;
06100 BEGIN
06200 INTEGER N ;
06300 DBREAK ; PASS ; N ← CVD(E("0",NULL)) MIN 50 ;IF N<1 THEN N←50 ; IF ¬ON THEN RETURN ;
06400 TWEENLFM ← N-1; SINCELFM ← 0; BREAKM ← 5;
06500 END "DSUPERIMPOSE" ;
00100 RECURSIVE PROCEDURE DSKIP(BOOLEAN GRPSKIP) ;
00200 BEGIN
00300 BOOLEAN GM ;
00400 DBREAK ; PASS ;
00500 IF GRPSKIP THEN BEGIN GM←GROUPM ; GROUPM ←1 ; END ;
00600 IF ITS(TO) THEN
00700 BEGIN "SKIP TO"
00800 DAPART ; PASS ;
00900 IF ITS(COLUMN) THEN BEGIN PASS; TOCOLUMN(CVD(E(CVS(COL+1),NULL))) END
01000 ELSE BEGIN IF ITS(LINE) THEN PASS ; TOLINE(CVD(E("1", NULL))) END ;
01100 END "SKIP TO"
01200 ELSE SKIPLINES(IF THISTYPE>INTERNTYPE ∨ THISTYPE=-TERQ ∨ NEXTSCH(←) ∨ NEXTSCH(:)
01300 THEN 1 ELSE CVD(E("1", NULL))) ;
01400 IF GRPSKIP ∧ GM = 0 THEN DAPART ;
01500 END "DSKIP" ;
01600
01700 SIMPLE PROCEDURE DTABS ;
01800 BEGIN
01900 INTEGER NUMB, I ; BOOLEAN TOO ;
02000 IF ON THEN TABSORT[1] ← TWO(33) ; TOO ← FALSE ;
02100 DO BEGIN
02200 PASS ; NUMB ← CVD(E("-9999", NULL)) MIN 9999 ;
02300 IF ON THEN
02400 BEGIN
02500 FOR I ← 1 THRU 27 DO IF TABSORT[I] ≥ NUMB THEN DONE ; IF I>27 THEN TOO←TRUE;
02600 IF ¬TOO ∧ NUMB > -9999 THEN
02700 IF TABSORT[I] > NUMB THEN DO BEGIN TABSORT[I] ↔ NUMB ; I ← I + 1 END UNTIL TABSORT[I-1]=TWO(33) ;
02800 END ;
02900 END
03000 UNTIL ¬ITSCH(",") ;
03100 IF TOO THEN WARN("=","Too many Tab Stops") ;
03200 END "DTABS" ;
03300
03400 SIMPLE PROCEDURE DTURN(BOOLEAN TURNON) ;
03500 BEGIN
03600 comment TURN ON|OFF {"c" [FOR "c"]},... ;
03700 INTEGER C1, C2 ; STRING S1, S2 ;
03800 PASS ;
03900 IF THISTYPE>INTERNTYPE ∨ THISTYPE=-TERQ ∨ NEXTSCH(:) ∨ NEXTSCH(←) THEN
04000 BEGIN "TURN BACK"
04100 C1 ← IHED ;
04200 WHILE C1>0 ∧ (C2←IXTYPE(C1))≠MODETYPE ∧ (C2≠TURNTYPE ∨ ISTK[C1-1]<0) DO C1 ← IXOLD(C1) ;
04300 IF C2=TURNTYPE THEN DO BEGIN TURN((C2←ISTK[C1-1]) LSH -7,C2 LAND '177,1) ;
04400 ISTK[C1-1] ← -2 ; C1 ← IXOLD(C1) END UNTIL C1≤0 ∨ IXTYPE(C1)≠TURNTYPE ∨ ISTK[C1-1]<0 ;
04500 END "TURN BACK"
04600 ELSE BEGIN "TURN CHARS"
04700 PUSHI(TURNWDS, TURNTYPE) ; ISTK[IHED-1] ← -1 ;
04800 DO BEGIN
04900 IF ITSCH(",") THEN PASS ;
05000 S1 ← IF NOT ITS(TAB) THEN SIMPAR ELSE TB ; PASS ;
05100 COMMENT 2/27/73 TES ;
05200 IF ITS(FOR) THEN BEGIN PASS ; S2 ← SIMPAR ; PASS END ELSE IF TURNON THEN S2 ← S1 ELSE S2 ← NULL ;
05300 IF ON THEN
05400 BEGIN
05500 IF 0 ≠ LENGTH(S2) ≠ LENGTH(S1) THEN
05600 WARN(NULL,"Strings each side of FOR are unequal length") ;
05700 WHILE FULSTR(S1) DO
05800 TURN(LOP(S1), IF FULSTR(S2) THEN LOP(S2) ELSE 0, TURNON) ;
05900 END ;
06000 END UNTIL ¬ITSCH(",") ;
06100 END "TURN CHARS" ;
06200 END "DTURN" ;
06300
06400 SIMPLE PROCEDURE DUSERERR ; RKJ: 1-9-74;
06500 BEGIN "DUSERERR"
06600 STRING USER!MESSAGE;
06700 PASS;
06800 USER!MESSAGE ← E(NULL,NULL);
06900 IF ON THEN WARN("=",USER!MESSAGE);
07000 END "DUSERERR";
00100 INTEGER SIMPLE PROCEDURE COUNTERSTMT ;
00200 IF ITS(NEXT) THEN
00300 BEGIN
00400 INTEGER USYMB ; ie, unit name symbol number ;
00500 PASS ; USYMB←IF THISTYPE=UNITTYPE THEN SYMB ELSE IF THISTYPE=PUNITTYPE THEN -SYMB ELSE TWO(20) ;
00600 DNEXT ; RETURN(USYMB) ;
00700 END
00800 ELSE RETURN(0) ;
00900
01000 BOOLEAN SIMPLE PROCEDURE LABELDEF ;
01100 IF ¬NEXTSCH(:) THEN RETURN(FALSE)
01200 ELSE IF ¬ON THEN
01300 BEGIN
01400 WHILE THISISID ∧ NEXTSCH(:) DO BEGIN PASS ; PASS END ;
01500 IF ¬ COUNTERSTMT THEN E(0, 0) ; RETURN(TRUE) ;
01600 END
01700 ELSE
01800 BEGIN
01900 INTEGER LINK, PTR, PLIGHT, USYMB, WASSYMB, VALPTR ; STRING DEFVAL ;
02000 SIMPLE PROCEDURE CHECK!CONSISTENCY ;
02100 IF WASSYMB ∧ USYMB≠0 ∧ LDB(IXN(WASSYMB)) ≠ LDB(IXN(ABS(USYMB))) THEN
02200 WARN("=","Label "&SYM[LINK]&" was cross-referenced as a "&
02300 SYM[WASSYMB]&" but is being defined as a "&
02400 SYM[ABS(USYMB)]) ;
02500 LINK ← 0 ;
02600 DO BEGIN "MULTIPLE LABELS"
02700 PTR ← SYMNUM(THISWD&":") ; BYTEWD ← NUMBER[PTR] ;
02800 IF BYTEWD=0 OR ( PLIGHT ← LDB(PLIGHTWD(BYTEWD)) ) = 1 THEN
02900 BEGIN NUMBER[PTR] ← BYTEWD LSH 13 LOR LINK ; LINK ← PTR END
03000 ELSE WARN("=","Label "&SYM[PTR]&" is already defined as "&
03100 (IF PLIGHT=2 THEN STBL[IX] ELSE "a recent page number")) ;
03200 PASS ; PASS ;
03300 END "MULTIPLE LABELS"
03400 UNTIL ¬(THISISID ∧ NEXTSCH(:)) ;
03500 IF LINK = 0 THEN RETURN(TRUE) ; TES 11/29/73 ;
03600 DEFVAL ← IF (USYMB←COUNTERSTMT)=0 THEN E(0,0)
03700 ELSE IF USYMB>TWO(13) THEN "??"
03800 ELSE IF USYMB>0 THEN C! ELSE !;
03900 IF EQU(DEFVAL,0) OR USYMB = SYMPAGE THEN
04000 DO BEGIN "PAGE LABELS"
04100 NUMBER[LINK] ↔ PLBL ; WASSYMB ← PLBL LSH -13 ;
04200 CHECK!CONSISTENCY ;
04300 PLBL ↔ LINK ; LINK ← LINK LAND '17777 ; PLBL ← -PLBL ;
04400 END "PAGE LABELS"
04500 UNTIL LINK=0
04600 ELSE BEGIN "OTHER UNIT"
04700 VALPTR ← 2 ROT -2 LOR PUTS(DEFVAL&(IF XCRIBL THEN ALTMODE&CVS(XLENGTH(DEFVAL)) ELSE NULL)) ;
04800 DO BEGIN
04900 PTR ← VALPTR ; NUMBER[LINK] ↔ PTR ; WASSYMB ← PTR LSH -13 ;
05000 CHECK!CONSISTENCY ;
05100 LINK ← PTR LAND '17777 ;
05200 END
05300 UNTIL LINK=0 ;
05400 END "OTHER UNIT" ;
05500 RETURN(TRUE) ;
05600 END "LABELDEF" ;
00100 RECURSIVE BOOLEAN PROCEDURE ASSIGNMENT ;
00200 IF NEXTSCH(←) THEN
00300 BEGIN
00400 VASSIGN(SYMB, THISTYPE, IX, E(SPASS(PASS), 0)) ;
00500 IF ITSCH(;) THEN PASS ; RETURN(TRUE) ;
00600 END
00700 ELSE RETURN(FALSE) ;
00800
00900 BOOLEAN SIMPLE PROCEDURE EMPTYCHUNK ;
01000 RETURN(IF ITSCH(;) THEN IPASS(TRUE) ELSE FALSE) ;
01100
01200 BOOLEAN SIMPLE PROCEDURE NONSENSE(BOOLEAN VALID) ;
01300 BEGIN
01400 IF VALID THEN WARN("=","Can't make sense out of: "&SOMEINPUT) ;
01500 PASS ; RETURN(FALSE) ;
01600 END "NONSENSE" ;
00100 RECURSIVE BOOLEAN PROCEDURE COMMAND ;
00200 BEGIN
00300 DEFINE DB(WHAT) = "BEGIN IF ON THEN WHAT; PASS END",
00400 BDB(WHAT)="BEGIN IF ON THEN BEGIN DBREAK; WHAT END; PASS END";
00500 IF THATISID ∧ SYMLOOK(THISWD&THATWD) ∧ LDB(TYPEN(SYMBOL))=MANTYPE THEN
00600 BEGIN THISWD ← SYM[SYMB←SYMBOL] ; THISTYPE ← MANTYPE ;
00700 IX ← LDB(IXN(SYMB)) ; RDENTITY ; END
00800 ELSE IF THISTYPE ≠ MANTYPE THEN RETURN(FALSE) ;
00900 CASE IX OF
01000 BEGIN COMMENT COMMANDS ; comment THISWD is command word.;
01100 ie ADJUST ; BDB(JUSTM←1) ;
01200 ie AFTER ; DRESPONSE(2) ;
01300 ie APART ; BEGIN DAPART ; PASS END ;
01400 ie AREA ; DAREA(FALSE) ;
01500 ie AT ; DRESPONSE(1) ;
01600 ie BEFORE ; DRESPONSE(0) ;
01700 ie BEGIN ; BEGIN BEGINBLOCK(FALSE, IF ENDCASE=2 ∧ ON THEN -1 ELSE 1,
01800 IF THATISCON THEN SPASS(THATWD[2 TO ∞]) ELSE NULL) ; PASS END ;
01900 ie BELOW ; DBELOW ;
02000 ie BLANK PAGE ; DBLANKPAGE ;
02100 ie BOX FRAME ; DFRAME(TRUE) ;
02200 ie BREAK ; BEGIN DBREAK ; PASS END ;
02300 ie CC ; DCC ;
02400 ie CENTER ; BDB(BREAKM←4) ;
02500 ie CLOSE ; DCLOSE ;
02600 ie COMMAND CHARACTER ; DCOMMANDCHARACTER ;
02700 ie COMMENT ; BEGIN IMPOSSIBLE("COMMAND") ; PASS END ;
02800 ie COMPACT ; DB(SPACEM←IF FILL THEN 1 ELSE 2) ;
02900 ie CONTINUE ; BEGIN DBREAK ; NOPGPH ← 1 ; PASS END ;
03000 ie COUNT ; DCOUNT ;
03100 ie CRBREAK ; DB(CRBM←1) ;
03200 ie CRSPACE ; DB(CRBM←0) ;
03300 ie DEVICE ; DDEVICE ;
03350 ie DONE ; DDONE ;
03400 ie END ; CASE IF STARTS THEN 0 ELSE ENDCASE OF BEGIN STARTEND; BEGINEND; ONCEEND; RESPEND END ;
03500 ie FILL ; BDB(BREAKM ← 0 ; SPACEM ← SPACEM MIN 1) ;
03600 ie FLUSH LEFT ; BDB(BREAKM←2) ;
03700 ie FLUSH RIGHT ; BDB(BREAKM←3) ;
03800 ie FONT ; DFONT(FALSE);
03900 ie GROUP ; IF GROUPM THEN PASS ELSE BDB(GROUPM←1) ;
04000 ie GROUP SKIP ; DSKIP(TRUE) ;
04100 ie IF ; DCONDITIONAL ;
04200 ie INDENT ; DINDENT ;
04300 ie INSERT ; DINSERT ;
04400 ie JUSTJUST ; BDB(BREAKM←1) ;
04500 ie LET ; DLET ;
04600 ie LOCK ; DLOCK ;
04700 ie MACRO ; DMACRO(1) ;
00100 ie NARROW ; DMARGINS(1) ; COMMENT SEMI-OBSOLETE ;
00200 ie NEXT ; BEGIN PASS ; DNEXT END ;
00300 ie NOFILL ; BDB(BREAKM←7) ;
00400 ie NOJUST ; BDB(JUSTM←0) ;
00500 ie ONCE ; BEGIN IF ON∧ENDCASE≠2 THEN BEGIN INTEGER S ; S ← STARTS ; STARTS ← 0 ;
00600 BEGINBLOCK(FALSE,2,ALTMODE) ; STARTS ← S ; END ; PASS END ;
00700 ie PACK ; DPACK ;
00800 ie PAGE FRAME ; DFRAME(FALSE) ;
00900 ie PICHAR ; DPICHAR ;
01000 ie PLACE ; BEGIN IF ON THEN DBREAK ; PASS ; PLACE(IX) ; PASS END ;
01100 ie PORTION ; DPORTION ;
01200 ie PREFACE ; BEGIN DBREAK; PASS; K←CVD(E("0",NULL)); IF ON THEN IF FILL THEN LEADFM←K ELSE LEADNM←K END ;
01300 ie RECEIVE ; DRECEIVE ;
01400 ie RECURSIVE MACRO ; DMACRO(0) ;
01450 ie REPEAT ; DREPEAT ;
01500 ie REQUIRE ; DREQUIRE ;
01600 ie RETAIN ; DB(SPACEM←0) ;
01700 ie SELECT ; DFONT(TRUE) ;
01800 ie SEND ; DSEND ;
01900 ie SHOW ; DSHOW ;
02000 ie SKIP ; DSKIP(FALSE) ;
02100 ie START ; BEGIN BEGINBLOCK(FALSE,0,IF THATISCON THEN SPASS(THATWD[2 TO ∞]) ELSE NULL) ; PASS END;
02200 ie SUPERIMPOSE ; DSUPERIMPOSE ;
02300 ie TABS ; DTABS ;
02400 ie TEXT AREA ; DAREA(FALSE) ;
02500 ie TITLE AREA ; DAREA(TRUE) ;
02600 ie TURN OFF ; DTURN(0) ;
02700 ie TURN ON ; DTURN(-1) ;
02800 ie USERERR ; DUSERERR ; RKJ: 1-9-74;
02900 ie VARIABLE ; DLOCAL ;
03000 ie VERBATIM ; BDB(BREAKM←6) ;
03100 ie WIDEN ; DMARGINS(-1) ; COMMENT SEMI-OBSOLETE ;
03200 END ; COMMENT COMMANDS ;
03300 IF ITSCH(;) THEN PASS ;
03400 RETURN(TRUE) ;
03500 END ;
00100 INTERNAL RECURSIVE BOOLEAN PROCEDURE CHUNK(BOOLEAN VALID) ;
00200 BEGIN
00300 IF PAGEMARKS > PAGEWAS THEN
00400 BEGIN comment, might be AT PAGEMARK response ;
00500 FOR PAGEWAS ← PAGEWAS + 1 THRU PAGEMARKS DO IF SIGNALD[FF] THEN RESPOND(SIGNALD[FF]) ;
00600 PAGEWAS ← PAGEMARKS ;
00700 END ;
00800 RETURN(THISISID AND (ASSIGNMENT OR LABELDEF OR COMMAND) OR TEXTLINE OR EMPTYCHUNK OR NONSENSE(VALID)) ;
00900 END "CHUNK" ;
01000
01100 INTERNAL SIMPLE PROCEDURE MANUSCRIPT ;
01200 BEGIN
01300 BOOLEAN VALID ;
01400 VALID ← TRUE ;
01500 DO VALID ← CHUNK(VALID) UNTIL LAST < 1 ;
01600 IF ¬NEXTS(7!MANUSCRIPT) THEN WARN("=","BRACKETS DON'T PAIR UP!!!!!!!!!") ;
01700 FINPORTION ; IF BLNMS=0 THEN BEGINEND ELSE IF BLNMS>0 THEN
01800 WARN("=",CVS(BLNMS) & " EXTRA BEGIN'S AND STARTS") ;
01900 END "MANUSCRIPT" ;
02000
02100 END "INNER BLOCK" ;
02200
02300 END "PARSER"